C ++:定义多个构造函数时的对象创建/销毁序列

时间:2017-03-21 11:20:37

标签: c++ c++11

运行以下简单代码(C ++ 11)

#include <iostream>
using namespace std;

class test {
public:
  int par;

  test(int par_) : par(par_) {
    cout << "constructor (par = " << par << " )" << endl;
  }

  test( int par_, char dummy) {
    test( (int)par_ );
  }

  test() { test(100); }


  // Copy constructor
  test(const test& x) { cout << "copy constructor (par = " << x.par << " )" << endl; }

  // Move constructor
  test(test&& x) { cout << "move constructor (par = " << x.par << " )" << endl; }

  // Copy assignemnt
  test& operator=(const test& x) { cout << "copy assignemnt (par = " << x.par << " )" << endl;  return *this; }

  // Move assignement
  test& operator=(test&& x) { cout << "move assignemnt (par = " << x.par << " )" << endl; return *this; }


  ~test() { cout << "destructor (par was " << par << " )" << endl; }
};


/****************************************************************************/

int main() {
  cout << "=========================" << endl;
  test tst_2(10, 0);

  cout << "=========================" << endl;
  test tst_1(5);

  cout << "=========================" << endl;
  test tst_0;

  cout << "=========================" << endl;

  cout << tst_2.par << " " << tst_1.par << " " << tst_0.par << endl;
  return 0;
}

我得到了输出

=========================
constructor (par = 10 )
destructor (par was 10 )
=========================
constructor (par = 5 )
=========================
constructor (par = 100 )
destructor (par was 100 )
=========================
-858993460 5 -858993460
destructor (par was -858993460 )
destructor (par was 5 )
destructor (par was -858993460 )

实际上对象tst_2和tst_0会立即被销毁......并在执行结束时再次销毁!

但是,如果我用以下

替换构造函数部分
:
  test(int par_) : par(par_) {
    cout << "constructor 1 param (par = " << par << " )" << endl;
  }

  test( int par_, char dummy) : par(par_) {
    cout << "constructor 2 params (par = " << par << " )" << endl;
  }

  test()  : par(100) {
    cout << "constructor 0 params (par = " << par << " )" << endl;
  }
:

这种行为正是我所期待的:

=========================
constructor 2 params (par = 10 )
=========================
constructor 1 param (par = 5 )
=========================
constructor 0 params (par = 100 )
=========================
10 5 100
destructor (par was 100 )
destructor (par was 5 )
destructor (par was 10 )

问题是:为什么第一个实现在创建后立即销毁对象(哪个构造函数调用另一个)?

2 个答案:

答案 0 :(得分:2)

test( int par_, char dummy)
{
    test( (int)par_ ); // secret is here!
}

在标记的行中,您正在堆栈中创建另一个对象,正好在构造函数中,在构造函数离开后再次销毁。如果你想做构造函数转发(尽可能从C ++ 11开始),你必须这样做:

test( int par_, char dummy) : test(par_)
{ }

默认构造函数(test(100);)中的所有内容。

答案 1 :(得分:0)

从两个构造函数中的构造函数体内调用test。因此,在构造函数内部调用的test是一个具有局部作用域的对象。一旦程序执行离开其中一个构造函数,就会销毁本地作用域test,从而调用析构函数。