C++ NRV 析构函数也可以控制?

文章探讨了C++中NRV(Non-RvalueReferenceOptimization)与类的拷贝构造和析构函数的关系。实验表明,存在拷贝构造或析构函数时,即使编译器未自动提供,类实例在return时仍会进行拷贝,反之则无NRV优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据深度探索C++对象模型中的说法,如果类未定义拷贝构造且编译器也不合成拷贝构造,编译器不会对这个类施加NRV优化,即函数中声明的局部变量类实例,在return到类外部的时候,会进行一次拷贝,如果有拷贝构造,不管是合成的还是用户主动定义的,这个时候都不会拷贝,因此我写了如下测试代码,注:测试版本为g++ 13.2.0

class testmove{
public:
    testmove(){
        printf("%p construct\n", this);
    }

    ~testmove(){
        printf("%p destruct\n", this);
    }

    testmove(const testmove &){

    }
};

testmove functestmove(){
    testmove t;
    printf("%p\n", &t);
    return t;
}

int main(){
    testmove t = functestmove();
    printf("%p\n", &t);
    return 0;

这时的打印为:
0x7ffeacdc7b63 construct
0x7ffeacdc7b63
0x7ffeacdc7b63
0x7ffeacdc7b63 destruct
这时有NRV优化,与预期相符,这时再去掉复制构造,其他的保持不变,此时类的定义更新为

class testmove{
public:
    testmove(){
        printf("%p construct\n", this);
    }

    ~testmove(){
        printf("%p destruct\n", this);
    }

    // testmove(const testmove &){

    // }
};

这时的输出为
0x7fff9f15c023 construct
0x7fff9f15c023
0x7fff9f15c023
0x7fff9f15c023 destruct
从输出来看是有NRV优化的,与学习的理论冲突了,检查类的实现发现没有成员变量,没有继承,没有虚函数,也没有虚继承,不应该合成复制构造函数,将构造和析构都去掉试试,此时的类testmove为空类,此时运行程序发现输出为:
0x7ffe3e5f1dbf
0x7ffe3e5f1e03
也就是说将构造和析构都去掉之后没有NRV优化,再将构造函数加上试试,结果还是一样,没有NRV优化加上析构函数,此时的输出如下
0x7ffe578a38b0 construct
0x7ffe578a38b0
0x7ffe578a38b0
0x7ffe578a38b0 destruct
此时是有NRV优化的,将析构函数注释,加上复制构造函数,输出如下:
0x7fff9a8c9f60 construct
0x7fff9a8c9f60
0x7fff9a8c9f60
也有NRV优化,至此得出以下结论:有析构函数或复制构造函数会施加NRV优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值