关于临时变量的分析,去掉编译器优化,linux环境下GDB调试

 分析一下代码,调用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)析构

如果采用编译器优化,则可省去临时对象的开销。

即只有一次构造,一次析构,运行结果如下:

猜你喜欢

转载自blog.csdn.net/znzxc/article/details/81191604