2017-03-09 4 views
0

Dies ist ein relativ einfacher Code, der einen überladenen Zuweisungsoperator und einen Multiplikationsoperator enthält. Ich habe ein Objekt nach Wert für beide Operatoren zurückgegeben. Was mich nervt ist, dass, wenn ich den Zuweisungsoperator verwende, der Kopierkonstruktor immer aufgerufen wird, während für den Multiplikationsoperator Kopierkonstruktoren niemals aufgerufen werden.Aufruf des Kopierkonstruktors beim Überladen des Operators für verschiedene Operatoren

#include<iostream> 
using namespace std; 
class foo { 
public: 
    int x; 
    foo() {x=1;} 
    foo(int a){x=a;} 
    foo(const foo &p){ 
    cout<<"CC:\tCopying from: "<<p.x<<'\t'<<&p<<"\tTo: "<<this<<endl; 
    } 
    foo operator=(const foo &r){ 
     cout<<"Assgn:\t"<<"Assigning from: "<<r.x<<'\t'<<&r 
      <<"\tTo: "<<this->x<<'\t'<<this<<endl; 
     return *this; 
    } 
    foo operator*(const foo &r){ 
     cout<<"Product:\t"<<"Multiplying from: "<<r.x<<'\t'<<&r 
      <<"\tTo: "<<this->x<<'\t'<<this<<endl; 
     return foo(x*r.x); 
    } 
}; 

int main() { 
    foo x(1),y(2); 
    foo z=x=y; 
    foo a=x*y; 
    x.x=1; y.x=2; 
    x*y*z; 
    x=y=z; 
    cout<<"X: "<<&x<<endl<<"Y: "<<&y<<endl<<"Z: "<<&z<<endl; 
} 

Hier ist der Ausgang:

Assgn: Assigning from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
CC: Copying from: 1 0x7fff2cddbf78 To: 0x7fff2cddbf68 
Product: Multiplying from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
Product: Multiplying from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
Product: Multiplying from: 7618584 0x7fff2cddbf68 To: 2 0x7fff2cddbf58 
Assgn: Assigning from: 7618584 0x7fff2cddbf68 To: 2 0x7fff2cddbf70 
CC: Copying from: 2 0x7fff2cddbf70 To: 0x7fff2cddbf48 
Assgn: Assigning from: 3 0x7fff2cddbf48 To: 1 0x7fff2cddbf78 
CC: Copying from: 1 0x7fff2cddbf78 To: 0x7fff2cddbf40 
X: 0x7fff2cddbf78 
Y: 0x7fff2cddbf70 
Z: 0x7fff2cddbf68 

Die grundlegende Sache ist, sind Kopierkonstruktoren nie, wenn sie aufgerufen wird, die Multiplikationsoperator (auch nicht verwendet wird, wenn ich eine Aussage wie foo ‚haben a = x * y '). Aber während der Wert von 'a = b' zurückgegeben wird, wird der Kopierkonstruktor genannt.

Ich weiß, dass Compiler-Optimierung einige Änderungen in der Ausgabe macht, und deshalb wird CC nicht aufgerufen, wenn ich eine Variable wie z = x = y oder z = x * y erklären. Aber warum wird CC bei der Rückgabe von x = y aufgerufen, wenn es z wie im Fall z = x * y direkt berechnen kann? Gibt es dafür einen bestimmten Grund? Wie, Zuweisungsoperatoren werden anders behandelt, oder, da ich *this im Zuweisungsoperator zurückgebe, unterscheidet es sich von dem Fall im Multiplikationsoperator, in dem ich eine temporäre Variable zurückgebe (dies sollte unwahrscheinlich sein, da ASFAIK der Compiler nicht in der Lage ist, Variablen zu unterscheiden lokaler und globaler Reichweite).

Antwort

0

Eine meiner Annahmen beim Versuch, eine Antwort zu erhalten, war falsch.

Ich habe das gleiche versucht, aber nur die Zuweisung Operatordefinition nur ein bisschen geändert, so dass ich zuerst den Wert in einer lokalen Variablen gespeichert und dann zurückgegeben. Und in diesem Fall wurde kein Kopierkonstruktor aufgerufen.

Dies bedeutet, dass der Compiler zwischen Variablen unterschiedlicher Bereiche unterscheiden kann und dies auch tut. Da der Code, den ich in der Frage gepostet habe, eine nicht-lokale Variable zurückgibt, wird der copy-constructor aufgerufen.

Ich rate das gleiche würde passieren (dh CC würde aufgerufen werden), wenn ich den Zuweisungsoperator von einer anderen Funktion außerhalb der Klasse aufrufen. Noch besser wäre es interessant zu sehen, was passiert, wenn CC von einer anderen Memberfunktion in derselben Klasse aufgerufen wird (obwohl es wahrscheinlich dasselbe wäre).

Verwandte Themen