示例1:
#include<iostream> using namespace std; class CDemo{ public: ~CDemo(){cout<<"destructor"<<endl;} }; void Func(CDemo obj){ cout<<"func"<<endl; } CDemo d1; CDemo Test(){ cout<<"test"<<endl; return d1; } int main(){ CDemo d2; Func(d2); Test(); cout<<"after test"<<endl; }
输出结果:
func destructor test destructor after test destructor destructor
程序工输出destructor四次。第一次是由于Func函数结束时,参数对象obj消亡导致的。第二次是因为:第20行调用Test函数,Test函数的返回值是一个临时对象,该临时对象在函数调用所在的语句结束时就消亡了,因此引发析构函数调用。第三次是main函数结束时d2消亡导致的。第四次是整个程序结束时全局对象d1消亡导致的。
示例2:
#include<iostream> using namespace std; class Demo{ int id; public: Demo(int i){id=i;cout<<"id="<<id<<"constructed"<<endl;} ~Demo(){cout<<"id="<<id<<"destructed"<<endl;} }; Demo d1(1); void Func(){ static Demo d2(2); Demo d3(3); cout<<"func"<<endl; } int main(){ Demo d4(4); d4=6; cout<<"main"<<endl; { Demo d5(5); } Func(); cout<<"main ends"<<endl; }
输出结果:
id=1constructed id=4constructed id=6constructed id=6destructed main id=5constructed id=5destructed id=2constructed id=3constructed func id=3destructed main ends id=6destructed id=2destructed id=1destructed
要分析程序的输出,首先要看看有没有全局对象。因为全局对象是进入main函数以前就形成的,所以全局对象在main函数开始执行前就会被初始化。本程序第9行定义了全局对象d1,因此d1初始化引发的构造函数调用,导致了第1行的输出结果。
main函数开始执行后,局部对象d4初始化,导致第2行的输出。
第18行,“d4=6;”,6先被自动转化成一个临时对象。这个临时对象的初始化导致第3行的输出。临时对象的值被赋给d4后,这条语句执行完毕,临时对象消亡,因此引发析构函数调用,导致第4行输出。
第21行的d5初始化导致第6行输出。d5的作用域和生存期都只到离它最近的,且将其包含在内的那一对“{}”中的"}"为止,即第22行的"}",因此程序执行到第22行时d5消亡,引发析构函数被调用,输出第7行。
第8行的输出是由于进入Func函数后,执行第11行的静态局部对象d2初始化导致的静态局部对象在函数第一次调用并执行到定义它的语句时初始化,生存期一直持续到整个程序结束,所以即使Func函数调用结束,d2也不会消亡。Func函数中的d3初始化导致了第9行输出。第23行,Func函数调用结束后,d3消亡导致第11行输出。
main函数结束时,其局部变量d4消亡,导致第13行输出。整个程序结束时,全局变量d1和静态局部变量d2消亡,导致最后两行输出。
新标准c++程序设计
转载请注明出处