2017-03-09 96 views
0

這是一個相對簡單的代碼,它包含一個重載賦值運算符和一個乘法運算符。我已經爲兩個操作符返回了一個對象的值。什麼是我的問題是,當我使用賦值運算符時,複製構造函數總是被調用,而乘法運算符則永遠不會調用複製構造函數。運算符在不同運算符重載時調用複製構造函數

#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 

基本的事情是,當乘法運算符的使用(甚至當我有類似foo「聲明從來沒有被稱爲拷貝構造函數A = X * Y')。但是在返回'a = b'的值時,複製構造函數被調用的是

我知道,編譯器優化,使輸出的一些變化,這就是爲什麼不調用CC當我宣佈樣z = x = yz = x * y的變量。但是,爲什麼當CC返回x = y時,爲什麼它可以直接計算z,就像z = x * y那樣?這有什麼特別的原因嗎?類似的,賦值運算符的處理方式不同,或者因爲我在賦值運算符中返回*this,它與乘法運算符中的情況不同,在該運算符中,我返回一個臨時變量(這應該不太可能,因爲ASFAIK,編譯器無法區分變量本地和全球範圍)。

回答

0

我試圖達到答案時的一個假設是錯誤的。

我試過同樣的事情,只是稍微改變了賦值操作符的定義,所以我首先將該值存儲在本地變量中,然後將其返回。在這種情況下,沒有複製構造函數被調用。

這意味着編譯器可以區別不同範圍的變量。由於我在問題中發佈的代碼返回非本地變量,因此調用了copy-constructor。

我猜測當我從類之外的其他函數調用賦值運算符時,會發生同樣的事情(即調用CC)。更好的是,看到CC在同一個類的不同成員函數中調用時會發生什麼(儘管它可能是相同的)會很有趣。