我正在学习C ++并且是StackOverflow的新手。对于测试代码,我正在观察相对于我期望的额外析构函数调用。下面是代码,后跟我的预期输出,然后是实际输出。
代码:
#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
我希望每个析构函数都与构造函数配对,但事实并非如此。为什么有额外的析构函数?
答案 0 :(得分:4)
您的operator=
声明了返回类型,但没有返回任何内容;这会导致未定义的行为。如果将其更改为
c_Test &operator= (const c_Test&) {
std::cout << "operator =" << std::endl;
return *this;
}
然后你会得到你期望的行为。
旁注:这超出了语言规范,因此不可靠,但怀疑您的编译器插入析构函数调用似乎是合理的,因为您声明的operator=
来自外面好像它返回了一个临时值(即好像它构造了一个需要销毁的对象),并且没有插入相应的构造函数调用,因为operator=
没有兑现它的这个承诺声明。
实际上,只是声明operator=
返回引用而不插入return
语句会使用gcc 4.9(没有优化)编译的代码显示预期的行为。用clang编译就崩溃了,就像它的右边一样。