运行以下简单代码(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 )
问题是:为什么第一个实现在创建后立即销毁对象(哪个构造函数调用另一个)?
答案 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
,从而调用析构函数。