C ++ - Construtor sobrecarga - privado e público
-
22-07-2019 - |
Pergunta
Você pode me dizer por que o seguinte código está me dando o seguinte erro - Chamada de sobrecarregado "C (int)" é ambígua
Gostaria de pensar que desde C (char x) é privado, apenas o C (float) ctor é visível do exterior e que deve ser chamado através da conversão de int para float.
Mas isso não é o caso.
class C
{
C(char x)
{
}
public:
C(float t)
{
}
};
int main()
{
C p(0);
}
Solução
Isto é discutido em "Effective C ++" por Scott Meyer. A razão que esta é ambígua é que eles queriam para garantir que apenas alterar a visibilidade de um membro não mudaria o significado do código já existente em outro lugar.
Caso contrário, suponha que a classe C estava em algum lugar do cabeçalho. Se você tivesse um membro privado C (int), o código apresentar chamaria C (float). Se, por algum motivo, o (int) membro C foi tornado público, o código antigo de repente chamar esse membro, embora nem o código antigo, nem a função que chamou havia mudado .
EDIT: Mais motivos:
Ainda pior, suponha que você tinha as 2 funções seguintes:
C A::foo()
{
return C(1.0);
}
C B::bar()
{
return C(1.0);
}
Estas duas funções poderia chamar funções diferentes dependendo se quer foo ou bar foi declarado como um amigo de C, ou se herda A ou B a partir dele. Tendo idênticas chamar código funções diferentes é assustador.
(que é provavelmente não tão bem colocado como discussão de Scott Meyer, mas essa é a idéia.)
Outras dicas
0 é um tipo int
. Uma vez que pode ser fundido implicitamente, quer um flutuador ou carvão animal igualmente, a chamada é ambígua. A visibilidade é irrelevante para esses fins.
De qualquer colocar 0.0
, 0.
, ou 0.0f
, ou se livrar do construtor C(char)
inteiramente.
Editar: parte relevante do padrão, a secção 13.3:
3) [...] Mas, uma vez que as funções candidatos e listas de argumentos foram identificados, a seleção da melhor função é a mesma em todos os casos:
- Em primeiro lugar, um subconjunto de funções, aqueles candidatos que têm o número correto de argumentos e cumprir certas outras condições, é selecionado para formar um conjunto de funções viáveis ??(13.3.2).
- Em seguida, a melhor função viável é seleccionado com base nas sequências de conversão implícitos (13.3.3.1) necessários para combinar cada um argumento para o parâmetro correspondente de cada função viável.
4) Se uma melhor função viável existe e é único, resolução de sobrecarga bem sucedido e produz como resultado. Caso contrário sobrecarga resolução falhar e a chamada é mal formado. Quando a resolução de sobrecarga bem-sucedido, e a melhor função viável não é acessível (cláusula 11) no contexto em que ela é usada, o programa é mal-formado.
Note que a visibilidade não é parte do processo de seleção.
Eu não acho que:
C p(0);
está sendo convertido em:
C(float t)
Você provavelmente precisará fazer:
C p(0.0f);