构造函数中的额外析构函数,复制构造函数,C ++中的析构函数序列

时间:2015-04-21 16:45:21

标签: c++ constructor destructor copy-constructor

我正在学习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

我希望每个析构函数都与构造函数配对,但事实并非如此。为什么有额外的析构函数?

1 个答案:

答案 0 :(得分:4)

您的operator=声明了返回类型,但没有返回任何内容;这会导致未定义的行为。如果将其更改为

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

然后你会得到你期望的行为。

旁注:这超出了语言规范,因此不可靠,但怀疑您的编译器插入析构函数调用似乎是合理的,因为您声明的operator=来自外面好像它返回了一个临时值(即好像它构造了一个需要销毁的对象),并且没有插入相应的构造函数调用,因为operator=没有兑现它的这个承诺声明。

实际上,只是声明operator=返回引用而不插入return语句会使用gcc 4.9(没有优化)编译的代码显示预期的行为。用clang编译就崩溃了,就像它的右边一样。