本文描述个人对C++构造函数和析构函数何时调用的一些总结。
首先定义一个简单的class Test{
int m_i; int m_j; public: Test() { cout<<"Test()"<<endl; }
Test(const Test* object)
{
cout<<"Test(const Test* object)"<<endl
}
Test(int v) { cout<<"Test(int v)"<<endl; } ~Test() { cout<<"~Test()"<<endl; } };
第一种情况,直接调用。接下来看代码
int main() { Test a; Test b(1); Test c=5; Test d=c; // Test d(); cin.get(); }
这里需要特别注意Test d()这行,这里C++编译器是将它作为一个函数声明来实现的,实际上 d这个类成员并没有构造成功。
第二种情况类对象作为函数参数。
void func() { Test a(1); cout<<"****************"<<endl; Play(a); cout<<"****************"<<endl; Play(Test(5)); cout<<"****************"<<endl; Play(2); cout<<"****************"<<endl; Play1(a); cout<<"****************"<<endl; }
我们将代码构造放在函数中实现,更方便查看析构的调用情况。
我分别用了四种方式尝试函数传入类对象。
1.先构造一个类,将他作为函数实参。
2.函数实参是一个类对象的构造。
3.函数实参是一个整数。
4.函数实参是一个类引用,引用一个类对象。
我们将代码运行后结果如下
可以看到
第一种情况会进行一次复制操作和俩次析构操作。
而第四种情况引用传递类对象则进行一次析构。
而二三两种情况效果相同,都只是进行一次构造和两次析构。
第三种情况类作为返回值
Test func() { Test a(1); return a; } int main() { Test b=func(); cout<<"*****************"<<endl; Test a(1); a=func(); cin.get(); }
先看到结果
可以看到当在类对象声明时用函数返回值给对象赋值,并没有构造发生。
当用函数返回值给一个类对象赋值时,会调用一次构造和一次析构。原因是函数返回值会先构造一个和返回对象一样的临时类,然后将其返回,待操作结束后,释放该临时类
总结
1.当类直接作为函数参数时,会发生一次拷贝动作,同时进行2次析构动作。
2.当在函数参数中直接构造一个类,或者符合C++自动构造规则的,则调用一次构造和两次析构。
3.当类作为函数引用参数时,进行一次析构。
4当类作为返回值时,
如果直接在类声明处用函数返回值初始化,那么什么都不做。
如果普通的用函数返回值赋值给一个类对象,则进行一次构造,一次析构。