先给一个类A:
class A { public: A(){ printf("structor "); }; public: ~A(){ printf("destructor"); }; }
//代码1 //注意C函数的实现与代码2不同 A* C(A *a){ return a; } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { A b; A *d = C(&b); }
//代码2 A C(A a){ return a; } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { A b; A d = C(b); }
A C(){ A f; return f; } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { A b; A d = C(); }
代码一,构造与析构分别为一次,而且析构为在tmain主函数结束的时候进行
代码二,构造执行一次(此外还执行了2次拷贝构造,编译器会帮你实现一个拷贝构造函数,只是这个函数为空的,什么都不执行,可以自己写个拷贝构造函数测试 ,A(const A&){ printf("copy structor ");} 。第一次拷贝构造在C(b)时执行,还有一次在 return a 时执行,因为会产生一个临时对象);
析构执行了三次,第一次析构为 return a 的时候执行(是 a 对象 执行了此次析构),第二次第三次析构均为tmain主函数结束后执行
分别是d 和b ,这也从侧面证实了前几天看到的一个观点,有些编译器会让d直接为这个临时对象,而不会在单独创建d,然后把临时对象复制给d,接着销毁临时对象(这里困扰了好久,一直认为过程应该为红色部分,这样应该会有2次拷贝构造,一次是C(b),还有一次为 A d= 的过程,突然想起前几天看到的蓝色字体观点,才醒悟,太健忘了)
代码三,构造先执行两次(分别为 A b 与 A f ),然后拷贝构造函数执行了一次,析构为三次
拷贝构造执行在 return f(产生了一个临时对象) , 析构一次在 return f (对象 f 销毁,执行了析构)时,还有两次在tmain 快结束时执行;
对于拷贝构造函数,来看下以下的说明:
在C++中,下面三种对象需要调用拷贝构造函数:
1) 一个对象以值传递的方式传入函数体;
2) 一个对象以值传递的方式从函数返回;
3) 一个对象需要通过另外一个对象进行初始化;
经测试发现 : 对于 A d = C(b); 这种形式,只执行两次拷贝。不会因为满足1,2和3条件,执行3次拷贝构造。 具体原因就是
“有些编译器会让d直接为这个临时对象,而不会在单独创建d,然后把临时对象复制给d,接着销毁临时对象(这里困扰了好久,一直认为过程应该为红色部分,这样应该会有2次拷贝构造,一次是C(b),还有一次为 A d= 的过程,突然想起前几天看到的蓝色字体观点,才醒悟,太健忘了)”这段话了
若就执行C(b),而不是 A d = C(b) ,则 产生的临时对象会在函数C(b)执行完后,销毁,使用析构