2012-10-05 24 views
3

我寫這個代碼:爲什麼X(X&)可以被調用兩次?

struct X{ 
     int val; 

     void out(const string& s, int nv) 
      {cerr<<this<<"->"<<s<<": "<<val<<"("<<nv<<")\n";} 

     X() {out("X(int)",0); val=0;} 
     X(int v){out("X(int)",v); val=v;} 
     X(const X& x){out("X(X&)",x.val); val=x.val;} 
     X& operator=(const X& a) 
      {out("X::operator=()",a.val); val=a.val; return *this;} 
     ~X() {out("~X()",0);} 
    }; 

    X copy(X a) {return a;} 

    int main{ 
     X loc2; 
     X loc(5); 
     loc2 = copy(loc); 
     return 0; 
    } 

的輸出是這(在VS2010):

003BFAA0->X(int): -858993460(0) 
003BFA94->X(int): -858993460(5) 
003BF964->X(X&): 723486321(5) 
003BF994->X(X&): -858993460(5) 
003BF964->~X(): 5(0) 
003BFAA0->X::operator=(): 0(5) 
003BF994->~X(): 5(0) 

的前兩行的罰款。但第三行和第四行顯示它將X(X &)稱爲兩次。副本(X a)中只有一個「X a」。爲什麼X(X &)可以被調用兩次?

回答

6

爲什麼X(X&)可以被調用兩次?

通過函數調用:

loc2 = copy(loc);  

copy(loc);調用拷貝構造函數兩次:

  1. 要創建參數loc的副本被傳遞給函數。
  2. 創建返回對象a的副本。

在C/C++函數的參數是由值默認通過。因此,不是實際的參數,而是在函數調用中接收到傳遞的對象/變量的副本。此副本通過調用複製構造函數來創建。
您的copy()函數也返回值再次導致複製構造函數被調用。

注意,在某些情況下,編譯器可能的Elid(刪除)調用拷貝構造函數和內聯構造的對象,這種現象被稱爲複製省略。一般情況下,你should'nt寫它產生基於副作用的代碼複製構造函數被調用的次數。

1

執行「return a」時,由於返回類型爲X(不是X &),因此創建類型X的對象的副本。 (如果它是X & - 它也會是一個錯誤 - 複製函數的形式參數「a」是一個局部範圍的變量)

相關問題