2011-08-28 53 views
0

編輯:對不起,我在原始文章中使用了「賦值構造函數」而不是「賦值運算符」。現在修復。爲什麼不在這裏調用操作符?

事實證明,在以下代碼中調用複製構造函數而不是賦值運算符。任何人都可以告訴我背後的原因?謝謝。

class A 

{ 
int i; 
public: 
A(int ii) { i = ii; } 
A(const A& a) { i = a.i; i++; } 
A& operator=(const A& a) { i = a.i; i--; } 
}; 
int main(void) 
{ 
A a(4); 
A b = a; 
return 0; 
} 
+2

該代碼是否可以編譯?你不會從'operator ='返回任何東西(這不是一個構造函數)。 – Mat

+0

它在g ++中編譯得很好。 – EXP0

+0

'警告:函數返回非空無返回聲明。使用'-Wall'併爲自己節省一大筆麻煩。 – Mat

回答

7
A a(4); 
A b = a; 

沒有一個是轉讓。兩者都是初始化。

第一個被稱爲直接初始化,第二個被稱爲複製初始化。

它們之間的區別在於,第一個會工作,即使拷貝構造函數是無法訪問(即其要麼privateprotected)如果拷貝構造函數是不能被訪問,第二個是行不通的。

即使第二個需要複製構造函數是可訪問的,這並不意味着複製構造函數將被調用。允許編譯器對此進行優化,因此可以將調用完全拋棄到複製構造函數。語義驗證需要可訪問的複製構造函數。

請參閱以下主題:

1並沒有什麼所謂的等「轉讓構造」的事情。

+1

非常感謝你的詳細解釋。如果兩者都起作用,它們在效率方面有什麼不同?謝謝。 – EXP0

+0

@ EXP0:一個好的編譯器會爲兩者生成相同的機器指令。所以在效率方面他們不應該有任何區別。 – Nawaz

4

operator=不是「轉讓構造函數」,它是一個「賦值運算符」。

當您在其定義中初始化變量時(如A b = a),它在定義上等同於調用複製構造函數。即A b(a);A b = a;完全相同。

+2

注意:這僅適用於任何未標記爲明確的構造函數。任何顯式的構造函數*都不能與等號表示法一起使用;你必須明確地構造它。 –

+0

@bdonlan - 你可以證實,這是C++標準所要求的,還是僅僅是一些編譯器實現的優化(即用一次調用複製構造函數替換默認構造函數,然後是賦值運算符)? – AAT

+0

這是標準要求的。即使對於沒有默認構造函數的類,也可以這樣做。 – bdonlan

相關問題