2013-07-01 7 views
6

ho semplicemente creato una classe come questa:A proposito di costruttori e assegnare operatori C++

class GreatClass 
{ 
public: 
    GreatClass(){cout<<"Default Constructor Called!\n";} 
    GreatClass(GreatClass &gc){cout<<"Copy Constructor Called!\n";} 
    GreatClass(const GreatClass &gc){cout<<"Copy Constructor (CONST) Called!\n";} 
    ~GreatClass(){cout<<"Destructor Called.\n";} 
    GreatClass& operator=(GreatClass& gc){cout<<"Assign Operator Called!";return gc;} 
    const GreatClass& operator=(const GreatClass& gc){cout<<"Assign Operator (CONST) Called!";return gc;} 
}; 

GreatClass f(GreatClass gc) 
{ 
    return gc; 
} 

e nella funzione main(), ci sono due versioni:

versione # 1:

int main() 
{ 
    GreatClass g1; 
    GreatClass G = f(g1); 
} 

versione # 2:

int main() 
{ 
    GreatClass g1; 
    f(g1); 
} 

Essi tutto genera lo stesso uscita:

Default Constructor Called! 
Copy Constructor Called! 
Copy Constructor Called! 
Destructor Called. 
Destructor Called. 
Destructor Called. 

non capisco il motivo per cui non v'è niente di che accade quando sto assegnando f(g1)-G. Quale costruttore o operatore è chiamato a questo punto?

Grazie.

+4

Copia elision è quello che sta succedendo. Se stai usando GCC, prova il flag di compilazione '-fno-elide-constructors'. –

+0

Penso che forse parte della tua confusione sia il motivo per cui "operator =" non viene usato. Questo è dettato dallo standard. Le cose della forma 'A a2 = a1;' sono inizializzazione della copia e viene utilizzato il costruttore di copie (non l'operatore di assegnazione). Anche l'elisione di copia può entrare in gioco. – huskerchad

risposta

13

Le implementazioni del compilatore possono escludere/rimuovere le chiamate del costruttore della copia in alcuni casi, l'esempio specificato è un esempio di utilizzo valido di tale scenario. Invece di creare un oggetto temporaneo e quindi copiarlo sull'oggetto di destinazione, l'oggetto viene creato direttamente nell'oggetto di destinazione e la chiamata del costruttore di copie viene rimossa.

Questa ottimizzazione è conosciuto come Copia elisione attraverso Return value optimization.

Inoltre, con C++ 11 move semantics through rvalue references è possibile avviare invece della semantica Copia. Anche con la semantica del movimento i compilatori sono ancora liberi di applicare RVO.