#include <iostream> using namespace std; class a { public: a(const a & ia) {} a(a & ia) {} /* 在VS2005 中认定和上一个拷贝构造函数是相同的 */ a() {} }; a foo (a obja) { a oa; return oa; } int main(void) { a a1; a a2 = foo(a1); //a a3 = foo(a1 ); return 0; }
上面的测试程序在 在GCC 中,没有a2 单独的创建对象,而是直接使用了函数foo 中的临时对象,那么在这个测试程序中对象a 被生成3次,析构3次;在VS2005 中,对象a 被构造4次,拷贝构造函数被调用两次。
如果加入 a a3 = foo(a1) 的语句,可以发现GCC 编译的程序 a 对象被创建了 5 次,而 VS2005 中,对象a被创建7 次。
分析:对象 a1 的创建都是相同的,在调用 foo(a1) 的时候,都会在内存中创建一个 a 对象,通过拷贝构造函数对参数obja 赋值,在函数 foo 中 生成对象实例 oa ,到这里两者都是相同的,而在函数foo 返回对象oa 的时候,GCC 中并没有重新创建对象 a2 和 a3 ; 而 VS2005 中会创建新的对象,新的对象通过拷贝构造函数赋值 (a2 = obja; a3 == obja) 这也是为什么foo 函数被调用一次,VS2005 中a 对象比 GCC 中的a 对象多1 个,在调用一次,对象a 又多1 个。 GCC 对于函数返回C++ 对象进行了优化,直接使用了堆栈中的对象(不知道GCC 内部究竟是怎么处理的,没有深入研究改对象是否真的在堆栈,如果在堆栈中,那么堆栈被破坏之后,如何依然保持对象的完整性呢?)