int main() {
int theInt = 5;
/**
* Constructor "Example(int val)" in effect at the statement below.
* Same as "Example exObject(theInt);" or "Example exObject = Example(theInt);"
*/
Example exObject = theInt; // 1
Example ctr(5);
/**
* "operator unsigned int()" in effect at the statement below.
* What gets assigned is the value returned by "operator unsigned int()".
*/
int theInt1 = ctr; // 2
return 0;
}
Alla dichiarazione 1 viene chiamato il costruttore Example(int val)
. Dichiaralo come explicit Example(int val)
e otterrai un errore in fase di compilazione, vale a dire non sarà consentita alcuna conversione implicita per questo costruttore.
Tutti i costruttori a singolo argomento sono chiamati implicitamente se il valore assegnato è del rispettivo tipo di argomento. Utilizzando la parola chiave explicit
prima che i costruttori a singolo argomento disabilitino la chiamata del costruttore implicito e quindi la conversione implicita.
Se il costruttore è stato dichiarato esplicito, ovvero explicit Example(int val)
, si verificherà quanto segue per ciascuna istruzione.
Example exObject(theInt); // Compile time error.
Example exObject = theInt; // Compile time error.
Example exObject(Example(theInt)); // Okay!
Example exObject = Example(theInt); // Okay!
noti inoltre che in caso di chiamata al costruttore implicito e quindi conversione implicita il valore assegnato è un rvalue cioèun oggetto senza nome implicitamente creata usando un lvalue (theInt) che ci dice che in caso di conversione implicita del compilatore converte
Example exObject = theInt;
a
Example exObject = Example(theInt);
Così (in C++ 11) don' Prevedo che il costruttore lvalue sia chiamato vedendo che stai usando un lvalue, ovvero un valore con nome theInt
per l'assegnazione. Ciò che viene chiamato è il costruttore rval poiché il valore assegnato è in realtà l'oggetto non nominato creato usando il valore l. Tuttavia, questo si applica se si hanno entrambe le versioni lvalue e rvalue del costruttore.
Alla richiesta 2 operator unsigned int()
viene chiamato. Consideralo semplicemente come una normale chiamata di funzione con un nome strano e il fatto che possa essere chiamata automaticamente quando avviene una conversione implicita. Il valore restituito da quella funzione è il valore assegnato nell'espressione. E dal momento che nell'implementazione il valore restituito è un intero viene assegnato correttamente a int theInt1
.
Per essere precisisovraccarico ()
operatore che è l'operatore di trasmissione. Nel tuo caso è sovraccarico per int
quindi ogniqualvolta un oggetto della classe Example
viene assegnato a un int
il casting di tipo implicito da Example
a int
viene eseguito e quindi viene chiamato operator unsigned int()
. Pertanto,
int theInt1 = ctr;
è equivalente a
int theInt1 = (int)ctr;
@Zuzu: Ho notato che hai 'utilizzando namespace std;' vicino alla parte superiore del file. Immagino che il tuo docente o materiale didattico lo abbia in questo modo. In questo esempio non ne hai bisogno, ma fai attenzione a dove lo usi. ** Mai ** mai usarlo in un file di intestazione - può causare un dolore indicibile se si desidera utilizzare nomi che si trovano nello spazio dei nomi 'std'. Considera di non usarlo affatto, ma se sei come me potresti voler usarlo solo nei moduli (file .cpp) e dopo tutto # include, ma prima delle definizioni di funzioni e metodi. – quamrana
Qual è la tua domanda? –