2012-10-02 83 views
4

當我讀到副本初始化VS直接初始化here。複製構造函數應調用複製初始化。爲什麼這裏複製構造函數不能調用?複製構造不調用

#include <iostream> 

using namespace std; 

class A{}; 

class B{ 
public: 
B(const A &a){cout << "B construct from A" << endl;} 
B(const B &b){cout << "B copy constructor" << endl;} 
}; 

int main(){ 
A a; 
B b = a; 
return 0; 
} 
+0

@LuchianGrigore:gcc版本4.6.3 20120306(紅帽4.6.3-2)(GCC) –

回答

5

這是複製Elision參考1:
拷貝構造函數調用而產生的臨時可能會被編譯器內聯創建對象進行優化,這是明確的C++標準允許的。

這是很好的證明在一個示例性的標準,以及:

C++ 03標準12.2臨時對象[class.temporary]
第2段:

[Example: 
class X { 
    // ... 
    public: 
    // ... 
    X(int); 
    X(const X&); 
    ˜X(); 
}; 
X f(X); 

void g() 
{ 
    X a(1); 
    X b = f(X(2)); 
    a = f(a); 
} 

這裏,實現可能在使用臨時使用X的副本,利弊它傳遞給f()之前構建X(2) tructor;或者,X(2)可能會在用於保存參數的空間中構建。另外,臨時可以用於在將其複製到`b using之前保留f(X(2))的結果,以及f。 ]

價1:
C++ 03 12.8複製類對象[class.copy]
第12段:

當滿足一定的條件,一個實現允許省略一個類對象的拷貝結構,即使拷貝構造和/或destructo R代表該物體有副作用.....

5

複製初始化仍然受複製elision,我猜這就是發生了什麼。從理論上講,臨時Ba構造和拷貝構造函數用於創建從臨時b。實際上,副本可以被優化。

要進行測試,可以使拷貝構造函數私有:

class B{ 
public: 
B(const A &a){cout << "B construct from A" << endl;} 
private: 
B(const B &b){cout << "B copy constructor" << endl;} 
}; 

,並得到一個編譯錯誤。這意味着編譯器期望複製構造函數是可訪問的,但不需要調用它。

複製省略在這裏觀察到的行爲可被改變的唯一情況。

+0

讀一遍,Luchian。我讀了它並得到了cpyctor沒有被調用(這意味着你和我的期望,但他沒有)。 – WhozCraig

+2

@WhozCraig複製構造函數沒有被調用,因爲它被優化了。 –

+0

爲什麼它會被調用?該init的右側沒有'B'。 – WhozCraig