2014-11-04 39 views
3

在以下代碼:這是誰的析構函數?

#include <string> 
#include <iostream> 

struct S { 
    std::string a; 
    int b; 

    S(const S&) = default; 
    S(S&&) = default; 
    S& operator=(const S&) = default; 
    S& operator=(S&&) = default; // not required here but should be added for completeness 

    ~S() { 
     std::cout << a << " " << b << std::endl; 
    } 
}; 

S f(S arg) { 
    S s0{}; 
    S s1(s0); //s1 {s0}; in the book 
    s1 = arg; 
    return s1; 
} 

int main() 
{ 
    S s3{"tool",42}; 
    f(s3); 
} 

我得到以下輸出(I評論與我的推理輸出):

42 //??? 
0 // s0 is destroyed 
tool 42 // arg is destroyed 
tool 42 // return value of f() is destroyed 
tool 42 // s3 is destroyed 

其析構函數是輸出42的一個??我不明白

+1

我似乎無法重現此。你能告訴我們你正在使用哪個平臺,編譯器和編譯命令行嗎? – SirDarius 2014-11-04 11:11:07

+0

[cnr](http://ideone.com/qDoRSg)。 – WhozCraig 2014-11-04 11:11:17

+0

除了第一行中的「42」之外,我都可以得到所有的東西。你已經肯定使用C++ 11出現,整個 「默認」 的經營.... 語言: C++ 11創建 : 0秒前 知名度: 公共\t 分享或嵌入源代碼的 ha9u63ar 2014-11-04 11:15:41

回答

2

自動變量聲明相反的順序被破壞,所以指示的析構函數的s1析構函數。

在程序中當時取值{"", 42}的原因是f的返回值正在通過移動構建來初始化;即s1正在被視爲一個xvalue。這是根據在[class.copy]/32的規則:

當的複製操作的省音的標準被滿足或一個事實,即所述源 對象是一個函數參數將滿足節省,並且要複製的對象由左值指定,重載解析到 選擇複製的構造函數首先執行,就好像該對象由右值指定一樣。

+0

這是有趣的是,這種行爲被觸發,例如由G ++'-fno-的Elid-constructors'選項,禁用這個特定的優化。 – SirDarius 2014-11-04 13:09:22