2013-11-23 50 views
2
Line Line::operator =(Line ln) { 
     cout << "Assignment operator\n"; 
     Line temp; 
     temp.ptr = new int; 
     *temp.ptr = *(ln.ptr); 
     return temp; 
    } 

在上面的代碼,當執行下面的語句拷貝構造函數不叫?函數返回時爲什麼不調用複製構造函數?</p> <pre><code>return temp; </code></pre> <p>自恢復是值的,爲什麼不叫拷貝構造函數:

感謝

+2

你的操作符實現是錯誤的:'operator ='應該返回一個* reference *到'* this',而不是一個新的對象。 –

+0

@Konrad:謝謝你指出這一點。所以你的意思是:* this.ptr = *(ln.ptr);並返回*這? – Iceman

+0

是的。整個'temp'對象是不必要的。但是,您也不應該在這裏使用(原始)指針。 C++提供了更好的機制。 –

回答

3

通過上述設置,編譯器極有可能會使複製構造函數不起作用,而是直接在預期返回值的位置構造臨時temp。即使複製構造函數具有副作用,也會明確允許複製elision。然而,即使拷貝被刪除,拷貝或移動構造函數仍然必須可訪問,即拷貝刪除的潛力不會放鬆相應構造函數的規則以便可訪問。

如果你覺得你絕對想擁有被稱爲拷貝構造函數,你可以強制拷貝構造,例如,通過將結果通過身份功能:

template <typename T> 
T const& identity(T const& object) { 
    return object; 
} 
// ... 
    return identity(temp); 

通常情況下,你會想要拷貝構造函數但是,被淘汰。

+0

該功能如何強制複製?它不是簡單地內聯,然後as-if規則生效嗎? –

+0

@KonradRudolph:不可以。語義是不同的,只有在非常特定的情況下才允許複製elision(詳見12.8 [class.copy]第31段):「...在具有類返回類型的函數的返回語句中,當表達式是 非易失性自動對象的名稱...「 –

+1

@KonradRudolph:複製elision是」as-if「規則的豁免。使用修改後的代碼,您不會返回局部變量,因此不再允許免除。 –

5

這就是所謂的複製省略:這是允許的按值返回時,一個本地對象,而不是本地對象不進行復印(你temp)直接構建在來電者。即使複製構造函數具有副作用,也可以這樣做。

2

我想補充以前的帖子,即使在構建目標對象時也省略了複製構造函數,它仍然可以被訪問和定義。例如,如果你的複製構造函數在編譯器發出錯誤時將其解析爲私有(除了MS VC++至少2010年有錯誤:))

相關問題