本文主要是介绍力学笃行系列之C++中的RVO优化,针对返回值为对象时临时对象的优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
摘要:
RVO (return value optimization) 和NRVO (named return value optimization) 是C++在处理一个函数返回类对象并将返回值赋给另一个对象时,为了减少拷贝构造次数以及析构次数而采用的一种编译器优化技术。
当函数的返回值为对象时,内部的调用是如何的,下面看例子:
#include <iostream>
using namespace std;
class Byte
{private: int b;public:Byte(int bb=0):b(bb){cout<<"constructor,address:"<<this<<endl;}Byte(const Byte& byte){b=byte.b;cout<<"copy constructor,address:"<<this<<endl;}const Byte operator++(int){ Byte before(b);b++;return before;}int getcr(){return b;}~Byte(){cout<<"deconstructor,address:"<<this<<endl;}
};int main()
{Byte tmp(10);const Byte tmp2=tmp++; //用一个对象来接受这个临时对象//const Byte* tmp2=&(tmp++);cout<<tmp2.getcr()<<endl;cout<<"compiler end"<<endl;
}
执行结果(g++加参数-fno-elide-constructors,去掉rvo优化):
constructor,address:0x7ffdb92f9a10 //tmp(10) 函数构造
constructor,address:0x7ffdb92f99e0 //构造before(b)
copy constructor,address:0x7ffdb92f9a30 //拷贝构造到临时对象
deconstructor,address:0x7ffdb92f99e0 //before调用析构函数
copy constructor,address:0x7ffdb92f9a20 //拷贝构造函数,从临时对象拷贝到tmp2
deconstructor,address:0x7ffdb92f9a30 //临时对象调用析构函数
10 //tmp.b的值为10
compiler end
deconstructor,address:0x7ffdb92f9a20 //程序结束,释放tmp2
deconstructor,address:0x7ffdb92f9a10 //程序结束,释放tmp
去掉-fno-elide-constructors,rvo优化,结果:
constructor,address:0x7ffca1a17170 //tmp构造函数
constructor,address:0x7ffca1a17180 //tmp2构造函数
10
compiler end
deconstructor,address:0x7ffca1a17180 //tmp析构函数
deconstructor,address:0x7ffca1a17170 //tmp2析构函数
接下来,将函数改为:
int main()
{Byte tmp(10);//const Byte tmp2=tmp++; const Byte* tmp2=&(tmp++); //用指针指向临时对象的地址cout<<tmp2.getcr()<<endl;cout<<"compiler end"<<endl;
}
程序运行结果:
constructor,address:0x7ffc4f9a3420 //tmp(10) 函数构造
constructor,address:0x7ffc4f9a33f0 //构造before(b)
copy constructor,address:0x7ffc4f9a3430 //拷贝构造到临时对象
deconstructor,address:0x7ffc4f9a33f0 //before调用析构函数
deconstructor,address:0x7ffc4f9a3430 //临时对象调用析构函数
10 //临时对象地址已经被释放(此处为何仍能输出10,此处留下一个疑问)
compiler end
deconstructor,address:0x7ffc4f9a3420 //程序结束,释放tmp
去掉-fno-elide-constructors,rvo优化,结果:
constructor,address:0x7ffedc840340 //tmp构造函数
constructor,address:0x7ffedc840350 //临时对象构造函数
deconstructor,address:0x7ffedc840350 //临时对象析构函数(为什么临时对象都释放掉了,还能调用函数得到b的值?)
10
compiler end
deconstructor,address:0x7ffedc840340 //tmp析构函数
此时,我本文的目的就达到了,就是返回的对象是一个临时对象,这个函数执行完之后,就会释放,其他还有各种函数返回值优化的验证模型,比如将return Byte(b++)会是什么结果?编译器是如何对这些语句进行优化的?NRVO是如何优化的?这些都可以在《在深度探索C++对象模型》中得到答案,我本文的目的已经达到,就不在深究了,大家如果感兴趣的话可以在深入研究下。
这篇关于力学笃行系列之C++中的RVO优化,针对返回值为对象时临时对象的优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!