2012-07-31 37 views
3
class A 
{ 
public: 

    A() 
    { 
     wcout << L"Empty constructed." << endl; 
    } 

    A (LPCWSTR Name) 
     : m_Name(Name) 
    { 
     wcout << L"Constructed." << endl; 
    } 

    friend void swap (A& Lhs, A& Rhs) 
    { 
     using std::swap; 

     swap(Lhs.m_Name, Rhs.m_Name); 
    } 

    A (A&& Other) 
    { 
     wcout << L"Move constructed." << endl; 

     swap(*this, Other); 
    } 

    A (const A& Other) 
     : m_Name(Other.m_Name) 
    { 
     wcout << L"Copy constructed." << endl; 
    } 

    A& operator= (A Other) 
    { 
     wcout << L"Assignment." << endl; 

     swap(*this, Other); 

     return *this; 
    } 

    ~A() 
    { 
     wcout << L"Destroyed: " << m_Name.GetString() << endl; 
    } 

private: 

    CString m_Name; 
}; 


int 
wmain() 
{ 
    A a; 

    a = A(L"Name"); // Where is the construction of this temp object? 

    return 0; 
} 

這是輸出我得到了上面的代碼:預期目標建設缺少

Empty constructed. 
Constructed. 
Assignment. 
Destroyed: 
Destroyed: Name 

見有註釋的行。我期望的是在那裏構造一個臨時對象,並且運算符中的參數Other將從該臨時對象獲得移動構造。這裏發生了什麼事?

+0

我的評論關於在標準中的位置是否指定複製elision可能會以可見的副作用進行復制問題中的答案。 – TripShock 2013-08-12 18:04:43

回答

8

「構造」的輸出實際上是來自該臨時對象構造的反饋。

如果您正在尋找拷貝分配操作員的參數Other的附加拷貝構造(或移動構造),可能會被複制刪除操作刪除。您的A(L"Name")立即構建並用作Other參數。不執行額外的複製(或移動)。

+0

是的,[copy elision](http://en.wikipedia.org/wiki/Copy_elision)是這裏發生的事情。 – JohannesD 2012-07-31 22:24:04

+0

標準中的什麼地方可以說這樣的事情可以完成?雖然copy elision只是一個簡潔的編譯器技巧,實際上並不是標準中提及的/所要求的東西?我相信我正在編譯優化關閉,順便說一句... – TripShock 2012-08-19 06:06:10

2

您可以使用交互式調試器來自己查看。然而,你的回答到「姓名」得到構造是這樣的:

A (LPCWSTR Name) 
    : m_Name(Name) 
{ 
    wcout << L"Constructed." << endl; 
} 

a = A(L"Name"); 

你的代碼的代碼行A a;構造一個空的對象。

然後它構建了「名稱」。

然後它交換了兩個的CString m_Name;(由輸出Assignment顯示)。

然後它破壞了原名爲「Name」的對象(A(L"Name"))。

然後它破壞了現在在其m_Name中持有「名稱」的原始空對象。