2013-07-01 11 views
6

ja po prostu stworzył klasę tak:O konstruktorów i przypisać operatorów w 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; 
} 

w funkcji main(), istnieją dwie wersje:

wersja # 1:

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

wersja # 2:

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

one wszystko generuje wyjście sam:

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

ja nie rozumiem, dlaczego nie ma nic się dzieje, kiedy jestem przypisywania f(g1) do G. Jaki konstruktor lub operator jest w tym momencie wywoływany?

Dzięki.

+4

Kopiowanie elizji jest tym, co się dzieje. Jeśli używasz GCC, spróbuj użyć flagi kompilacji '-fno-elide-constructors'. –

+0

Myślę, że być może częścią twojego zamieszania jest to, dlaczego 'operator =' nie jest używany. Jest to podyktowane przez standard. Rzeczy w postaci "A2 = a1;" są inicjowane podczas kopiowania i używany jest konstruktor kopii (a nie operator przypisania). Kopiowanie elizji może również wejść w grę. – huskerchad

Odpowiedz

13

Implementacje kompilatora mogą w niektórych przypadkach usuwać/usuwać wywołania konstruktora kopiowania, podany przykład jest dobrym przykładem użycia takiego scenariusza. Zamiast tworzyć obiekt tymczasowy, a następnie kopiować go do obiektu docelowego, obiekt jest tworzony bezpośrednio w obiekcie docelowym, a wywołanie konstruktora kopiowania jest usuwane.

Optymalizacja ta jest znana jako Copy elizji przez Return value optimization.

Również z C++ 11 move semantics through rvalue references może kopać zamiast semantyki Kopiuj. Nawet przy semantyzie ruchu kompilatory nadal mogą stosować RVO.

Powiązane problemy