分析一下代码,调用GetA()之后,在函数内会生成一个临时对象,调用一次构造函数,然后将此临时对象拷贝给函数的返回值,调用一次拷贝构造函数,此返回值也是一个临时对象,返回值再拷贝给a对象,调用一次拷贝构造函数。
总的来说,生成了3个对象,其中有2个是临时对象。
#include <iostream>
using namespace std;
int constructcount=0;
int copycount=0;
int destructcount=0;
struct A
{
A(){
cout<<"construct: "<<++constructcount<<endl;
}
A(const A& a){
cout<<"copy construct: "<<++copycount<<endl;
}
~A(){
cout<<"destruct: "<<++destructcount<<endl;
}
};
A GetA()
{
return A();
}
int main() {
A a = GetA();
return 0;
}
运行结果如下:
-fno-elide-constructors用来关闭返回值优化效果。
可见,确实生成了3个对象,调用了一次构造函数,两次拷贝构造函数。
那他们的析构时机又是怎么样的呢?
进行GDB调试
在上述位置加入断点,
进行单步调试,发现如下:
记 GetA()函数内生成临时对象(1),GetA()函数返回临时对象(2),最终对象(3),
函数内生成临时对象(1)构造---->函数返回临时对象(2)拷贝构造---->临时对象(1)析构---->最终对象(3)构造---->临时对象(2)析构---->最终对象(3)析构
如果采用编译器优化,则可省去临时对象的开销。
即只有一次构造,一次析构,运行结果如下: