2015-04-21 244 views
0

我正在學習C++,並且是StackOverflow的新增功能。對於測試代碼,我正在觀察與我期望的相關的額外析構函數調用。以下是我的預期輸出後跟實際輸出的代碼。C++中構造函數,複製構造函數,析構函數序列中的額外析構函數

代碼:

#include <iostream> 

class c_Test { 
    public: 
    c_Test() { std::cout << "Constructor" << std::endl; } 
    c_Test(const c_Test& x_in) { std::cout << "Copy constructor" << std::endl; } 
    c_Test operator= (const c_Test&) { std::cout << "operator =" << std::endl; } 
    ~c_Test() { std::cout << "Destructor" << std::endl; } 

}; 

int main() 
{ 
    c_Test t0, t1; // call constructor, constructor 
    c_Test t2 = t0;  // call copy constructor 
    t0 = t1;    // call operator= 

    return 0; // should call destructor, destructor, destructor 
} 

我預期的輸出是:

Constructor 
Constructor 
Copy constructor 
operator = 
Destructor 
Destructor 
Destructor 

什麼編譯並運行該程序後,我得到:

Constructor 
Constructor 
Copy constructor 
operator = 
Destructor 
Destructor 
Destructor 
Destructor 

我希望每一個析構函數是與構造函數配對,但事實並非如此。爲什麼會有額外的析構函數?

回答

4

您的operator=聲明返回類型,但不返回任何內容;這會導致未定義的行爲。如果您將其更改爲

c_Test &operator= (const c_Test&) { 
    std::cout << "operator =" << std::endl; 
    return *this; 
} 

然後您將得到您期望的行爲。

旁註:這是語言規範之外,因此不可靠,但它似乎是合理的懷疑您的編譯器插入一個析構函數調用,因爲operator=你宣佈從外面看起來好像返回臨時值(即,就像它構造了一個需要銷燬的對象一樣),並且沒有相應的構造函數調用被插入,因爲operator=沒有在它的聲明的承諾上做出妥協。

事實上,只是聲明operator=作爲返回引用而不是插入return語句使得使用gcc 4.9(沒有優化)編譯的代碼顯示預期的行爲。正如它的權利,它與崩潰編譯它崩潰。

+0

非常感謝。你的建議奏效了。 – StackUser2015

+0

@ StackUser2015如果這有助於你Wintermute的答案應該被接受。謝謝 –

相關問題