构造函数与析构函数(2)
今天突然想到,上次提及的构造函数的执行时刻还不够全面。当对象做为参数传入函数时,会不会也引发构造函数的执行?
先试试下面的代码
void FuncA(CParent objTemp) { cout<<"Begin of FuncA"<<endl; cout<<"End of FuncA"<<endl; } int main() { cout<<"Begin of main function"<<endl; CParent object; FuncA(object); cout<<"End of main function"<<endl; return 0; }
运行结果如下:
Begin of main function run constructor of CParent Begin of FuncA End of FuncA run destructor of CParent End of main function run destructor of CParent结果很神奇,居然跟我想像的完全不一样,构造函数调用了一次,而析构函数去调用了两次。知道传参的时候是会创建一个临时对象,那么构造函数应该会调用两次才对啊,难道直接把对象传进去不用创建临时对象? 那析构函数又为何调用了两次,没有两个不同的对象,哪来两个对象的析构....
跑去跟细菌讨论了一下,才知道原来还有拷贝构造函数这种东西。
在CParent类下添加一个方法如下:
CParent::CParent(const CParent& obj) { cout<<"run the copy destructor of CParent"<<endl; }再次运行程序:
Begin of main function run constructor of CParent run the copy destructor of CParent Begin of FuncA End of FuncA run destructor of CParent End of main function run destructor of CParent
结果如预期出现,果真是在传参时调用了拷贝构造函数,重新创建一个临时对象。这时我想,既然是创建了临时对象,那么在函数内部修改了对象属性,对原来的对象有没有影响?于是在类中添加一个属性,修改代码如下:
void FuncA(CParent objTemp) { cout<<"Begin of FuncA"<<endl; objTemp.n++; cout<<objTemp.n<<endl; cout<<"End of FuncA"<<endl; } int main() { cout<<"Begin of main function"<<endl; CParent object; object.n = 0; cout<<object.n<<endl; FuncA(object); cout<<object.n<<endl; cout<<"End of main function"<<endl; return 0; }
Begin of main function run constructor of CParent 0 run the copy destructor of CParent Begin of FuncA 1807010509 End of FuncA run destructor of CParent 0 End of main function run destructor of CParent
可以看出,不仅函数内改变临时对象属性并没对原对象产生影响,创建临时对象时也没有复制原对象的属性,使用这种方法传递对象是会出很大问题的。。。
那么有什么方法可以安全传递对象。我想指针是肯定没问题的,先不说,我想试试引用。
先修改代码如下:
void FuncA(CParent& objTemp) { cout<<"Begin of FuncA"<<endl; cout<<"End of FuncA"<<endl; } int main() { cout<<"Begin of main function"<<endl; CParent object; FuncA(object); cout<<"End of main function"<<endl; return 0; }
运行结果如下:
Begin of main function run constructor of CParent Begin of FuncA End of FuncA End of main function run destructor of CParent
构造函数跟析构函数都只调用了一次,应该是没有多创建对象了,不过我还是想证明一下。
再次修改代码:
void FuncA(CParent& objTemp) { cout<<"Begin of FuncA"<<endl; cout<<&objTemp<<endl; cout<<"End of FuncA"<<endl; } int main() { cout<<"Begin of main function"<<endl; CParent object; cout<<&object<<endl; FuncA(object); cout<<"End of main function"<<endl; return 0; }
运行一下:
Begin of main function run constructor of CParent 0013FDDC Begin of FuncA 0013FDDC End of FuncA End of main function run destructor of CParent

浙公网安备 33010602011771号