2012-10-17 145 views
0

當訂單構造函數/析構函數的這是析構函數/構造函數秩序正常,如果是這樣,爲什麼呢?返回一個對象

在下面的簡單函數

TemporaryObject SimpleFunction(); 
{ 
    TemporaryObject obj = MakeObj(); 

    // ... 

    return obj; // Stepping through at this point we hit TemporaryObject::dtor, MyObject::ctor 
} 

// At call site 
MyObject obj = SimpleFunction(); 

在return語句我預計MyObject的構造函數被調用,然後TemporaryObject析構函數被調用。 (可能會臨時對象首先被複制,但RVO在這裏是典型的)。

在VS2010(調試版本)會發生什麼事是TemporaryObject析構函數首先被調用,然後MyObject的構造函數與析構對象。查看內存地址確認它是被傳入的被破壞對象,如果有任何疑問,析構函數的副作用是顯而易見的。 (爲了完整起見,MyObject ctor在TemporaryObject中設置了一個標誌,標誌着它已經被複制了,TemporaryObject dtor聲明瞭這個標誌被設置了,這就是我知道在這種情況下'copy'之前破壞發生的原因) 。

+1

我真的懷疑這一點。向我們展示解決此問題的完整最小代碼。 –

+0

我對此表示懷疑 - 這是一個例子。 – Zero

+0

您需要發佈一個示例,其中包含在ctors和dector中修改的數據字段。 –

回答

1

最小的,完整的例子,使用答案

是的,dtor拷貝構造函數之前被調用,而不是原因,你似乎認爲。

關鍵的觀察是MyObject::dtor被調用兩次(在情況下,兩個不同的對象我們仍然傾向於跳轉到瘋狂的編譯器錯誤的結論)。所以我們猜測副本幕後發生的事情,果然,儘管你可能已經聽說編譯生成的拷貝構造函數,即使你提供不同的構造。

因此,如果您取消註釋了拷貝構造函數下面你會得到一些輸出,更好地描述發生了什麼,也正確處理mActive標誌

struct TemporaryObject 
{ 
    TemporaryObject() 
     : 
    mActive(true) 
    { 
     std::cout << "TemporaryObject::ctor mActive = " << mActive << ", this = " << (void*)this << std::endl; 
    } 

    /* TemporaryObject(const TemporaryObject& obj) 
     : 
    mActive(obj.mActive) 
    { 
     obj.mActive = false; 
     std::cout << "TemporaryObject::copy_ctor mActive = " << mActive << ", this = " << (void*)this << std::endl; 
    }*/ 

    ~TemporaryObject() 
    { 
     std::cout << "TemporaryObject::dtor mActive = " << mActive << ", this = " << (void*)this << std::endl; 
     // assert(!mActive); 
    } 

    mutable bool mActive; 
}; 

struct MyObject 
{ 
    MyObject(const TemporaryObject& obj) 
    { 
     std::cout << "MyObject::ctor obj.mActive = " << obj.mActive << ", &obj = " << (void*)(&obj) << std::endl; 
     obj.mActive = false; 
    } 
}; 

TemporaryObject SimpleFunction() 
{ 
    TemporaryObject obj; 

    // Do stuff 

    return obj; 
} 

int main() 
{ 
    MyObject obj = SimpleFunction(); 
} 

輸出:

TemporaryObject::ctor mActive = 1, this = 00EFF4AB 
TemporaryObject::dtor mActive = 1, this = 00EFF4AB 
MyObject::ctor obj.mActive = 1, &obj = 00EFF4D7 
TemporaryObject::dtor mActive = 0, this = 00EFF4D7 
+0

「是的,dtor是在複製構造函數之前被調用的,但不是出於你認爲的原因。」你的意思不是因爲**你似乎認爲。你基本上發佈了一個不正確的問題,聲稱是錯誤的,然後駁斥它,顯然是正確的答案。你應該刪除這個問題。 –

+1

你如何刪除這個問題?我投票結束它,只發布了答案,因爲有人建議我應該。是的,你,你或你都提到寫這個問題的白癡。 – Zero

0

當然你可以在調試版本中看到。由於在調試版本中沒有優化返回功能,它有以下規則:

TemporaryObject::ctor // Copy constructor 
TemporaryObject::dtor // of function local value that reach end of its scope! 
MyObject::ctor   // Create MyObject from returned value 
TemporaryObject::dtor // of function return value