C ++ - Sovraccarico del costruttore - privato e pubblico
-
22-07-2019 - |
Domanda
Puoi dirmi perché il seguente codice mi sta dando il seguente errore - chiamata di sovraccarico " C (int) " è ambiguo
Penso che dal momento che C (char x) è privato, solo il ctor C (float) è visibile dall'esterno e che dovrebbe essere chiamato convertendo int in float.
Ma non è così.
class C
{
C(char x)
{
}
public:
C(float t)
{
}
};
int main()
{
C p(0);
}
Soluzione
Questo è discusso in "C ++ efficace". di Scott Meyer. Il motivo per cui questo è ambiguo è che volevano garantire che la semplice modifica della visibilità di un membro non avrebbe cambiato il significato del codice già esistente altrove.
Altrimenti, supponi che la tua classe C fosse da qualche parte in un'intestazione. Se avessi un membro C (int) privato, il codice che presenterai chiamerebbe C (float). Se, per qualche motivo, il membro C (int) fosse reso pubblico, il vecchio codice improvvisamente chiamerebbe quel membro, anche se né il vecchio codice, né la funzione che ha chiamato erano cambiati .
EDIT: più motivi:
Ancora peggio, supponiamo di avere le seguenti 2 funzioni:
C A::foo()
{
return C(1.0);
}
C B::bar()
{
return C(1.0);
}
Queste due funzioni potrebbero chiamare funzioni diverse a seconda che sia foo o bar sia stato dichiarato amico di C o che A o B erediti da essa. Avere identiche chiamate in codice diverse funzioni è spaventoso.
(Probabilmente non è così ben definito come la discussione di Scott Meyer, ma questa è l'idea.)
Altri suggerimenti
0 è un tipo int
. Poiché può essere implicitamente castato su float o char allo stesso modo, la chiamata è ambigua. La visibilità è irrilevante per questi scopi.
Inserisci 0.0
, 0.
o 0.0f
, oppure rimuovi C (char)
costruttore interamente.
Modifica: parte pertinente dello standard, sezione 13.3:
3) [...] Ma, una volta identificate le funzioni candidate e gli elenchi di argomenti, la selezione della migliore funzione è la stessa in tutti i casi:
- Innanzitutto, viene selezionato un sottoinsieme delle funzioni candidate & # 8212; quelle che hanno il numero corretto di argomenti e soddisfano determinate altre condizioni & # 8212; per formare un insieme di funzioni vitali (13.3.2).
- Quindi viene selezionata la migliore funzione praticabile in base alle sequenze di conversione implicite (13.3.3.1) necessarie per abbinare ciascun argomento al parametro corrispondente di ciascuna funzione praticabile.
4) Se esiste la migliore funzione praticabile ed è unica, la risoluzione del sovraccarico ha esito positivo e la produce come risultato. In caso contrario, la risoluzione del sovraccarico non riesce e l'invocazione non è corretta. Quando la risoluzione del sovraccarico ha esito positivo e la migliore funzione praticabile non è accessibile (clausola 11) nel contesto in cui viene utilizzata, il programma non è corretto.
Nota che la visibilità non fa parte del processo di selezione.
Non penso che:
C p(0);
viene convertito in:
C(float t)
probabilmente dovrai fare:
C p(0.0f);