C++自制心得——类与对象(连续构造优化)
这是一个短篇专栏,不会花太长时间。这一章讲编译器对连续构造过程的优化,了解即可。
1. 匿名对象的有名化

用const&引用接收匿名对象会使匿名对象拥有名字,生命周期延长,与有名对象相同。
之前没讲这个,现在补上。
2. 优化
这是今天的重点
首先,我们来分析下面的代码
理论上调用第一个func函数需要经过构造+拷贝构造,第二个func函数也是如此,但编译器优化后结果却并非如此

只有第一个函数需要经过构造+拷贝构造,第二个函数就没有拷贝构造,这是编译器优化后的结果,编译器会优化同一语句中的连续构造+拷贝构造过程

同理,对于第三个函数编译器会使用1进行直接构造,而非构造+拷贝构造

这个也是优化后的结果
当然,这种行为不是C++标准行为,而是编译器自行决定的结果,不过鉴于所有新一代编译器均进行类似的优化操作,你还是把它当成C++特性吧

如果编译器没有优化,第一个函数调用会先构造aa,用aa拷贝构造临时对象,析构aa,用临时对象拷贝构造a1,析构临时对象
第二个函数会先构造a2,再构造aa,用aa拷贝构造临时对象,析构aa,用临时对象赋值a2,析构临时对象
两者效率上的差异就是一次拷贝构造与构造+赋值重载的差别

但是编译器优化了第一个函数调用中产生的临时对象,省掉了一次拷贝构造+析构,整个调用过程就变成了这样:构造aa,直接用aa拷贝构造a1,析构aa
对于第二个函数调用编译器就无法优化,因为不是连续的构造+拷贝构造

这段代码很有意思,如果编译器不优化,整个调用过程就会是构造匿名对象,用匿名对象拷贝构造临时对象,析构匿名对象,用临时对象拷贝构造a1,析构临时对象

编译器优化后就只剩一个构造了,整个调用过程就变成了用缺省值直接构造a1,省掉了所有中间步骤

同理,这么返回也是一个结果
综上,建议各位在写代码时尽量采取上述方式节约构造开销