これは、オーバーロードされた代入演算子と乗算演算子を含む比較的シンプルなコードです。私は両方の演算子の値によってオブジェクトを返しました。私が悩んでいるのは、代入演算子を使用すると、コピーコンストラクタは常に呼び出され、乗算演算子の場合、コピーコンストラクタは決して呼び出されないということです。ここで 異なる演算子の演算子オーバーロード中にコピーコンストラクタを呼び出す
#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;
}
は出力です:基本的な事がある
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
、乗算演算子は、i「はfooのようなステートメントを持っていない場合でも(使用されたときにコピーコンストラクタが呼び出されないさん= X * y ')。しかし、 'a = b'の値を返す間に、コピーコンストラクタは、と呼ばれます。
私はコンパイラの最適化が出力にいくつかの変更を加えることを知っています。そのため、z = x = y
やz = x * y
のような変数を宣言するとCCが呼び出されません。しかし、再びz = x * y
のようにz
を直接計算できるときにx = yを返すときにCCが呼び出されるのはなぜですか?これには特別な理由はありますか?同様に、代入演算子は異なる方法で扱われるか、代入演算子で*this
を返すので、一時変数を返す乗算演算子の場合とは異なります(これはASFAIKのためコンパイラが変数を区別できないためローカルおよびグローバルスコープの)。