2012-09-12 21 views
4

在以下代碼中,它輸出兩個不同的內存位置。這對我來說是有道理的,因爲我是以價值回報。複製構造函數的存在導致函數通過引用而不是值返回

#include <iostream> 

using namespace std; 

class Foo { 
public: 
     Foo() {} 
//  Foo (const Foo &) { cout << "Copy con" << endl; } 
}; 

Foo test() { 
     Foo foo; 
     cout << &foo << endl; 
     return foo; 
} 

int main() { 
     Foo foo = test(); 
     cout << &foo << endl; 
} 

然而,如果我去掉在上面的代碼拷貝構造並再次運行它,它輸出兩次相同的存儲器位置。爲什麼?它根本不打印出「Copy con」,所以我知道拷貝構造函數沒有被調用。看起來,僅僅存在一個拷貝構造函數會導致某種優化,即使它沒有被調用。

我正在編譯GCC 4.6.3上的「g ++ -Wall test.cpp -o test」。

+0

copy elision ... –

回答

2

這是return value optimization的結果。基本上,即使複製構造函數具有副作用,編譯器也會省略由return語句導致的代價高昂的複製操作。

這背後的推理是返回一個複雜的對象是昂貴的。編譯器不是在複製上浪費時間,而是在調用者的棧幀中祕密創建一個隱藏對象,並將該隱藏對象的引用傳遞給被調用函數,並將該函數的返回值直接複製到該隱藏對象中。

的C++非標準狀態這明確地(ISO-IEC 14882:2011 12.8第31段):

當滿足特定條件時,一種實現被允許省略 類的複製/移動施工對象,即使複製/移動對象的構造函數和/或析構函數具有副作用。

+2

那麼,爲什麼只有我聲明我自己的拷貝構造函數時纔會發生這種情況呢? –

+0

@Mike,只是因爲standart允許它:當滿足某些條件時,即使複製/移動構造函數和/或析構函數具有對象的類型,也允許實現省略類 對象的複製/移動構造副作用。「 - ISO-IEC 14882 12.8第31段。 – SingerOfTheFall

+3

@SingerOfTheFall:對於隱式定義的拷貝構造函數,non? –

相關問題