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).