2015-04-21 243 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的答案应该被接受。谢谢 –

相关问题