您的位置:首页 > 编程语言 > C语言/C++

More Effective C++ 条款20 协助完成"返回值优化(RVO)"

2015-09-24 21:01 337 查看
1. 函数如果返回对象,就会产生临时对象(见条款19)的构造,析构等过程,考虑以下重载的operator*:

Rational operator*(const Rational&lhs,const Rational&rhs){
return Rational(lhs.getNumerator()*rhs.getNumerator() +lhs.getDenominator()+rhs.getDenominator());
}


View Code
函数返回一个临时对象就传达给编译器这样一个信息:允许编译器在合适的时候采取RVO优化将消除临时对象的构造和析构成本,于是像这样的调用:

Rational c=a*b;//a和b是Rational型对象


编译器可以直接在c上构造a和b相乘的结果而不需要先将结果存储在一临时对象中,然后再拷贝给a(方法可能是将a作为参数传入operator*).这就是RVO:返回值优化.

3. 要实现RVO,编译器通常要求函数返回匿名对象,新式的编译器支持其进化版——NRV(named return value),它可以对具名返回值做优化,消除构造和析构临时对象的成本,也就是说,即使对第一种operator*实现版本,支持NRV的编译器仍然可以对于以下语句实行优化,消除临时对象的构造和析构:

Rational c=a*b;//a和b是Rational型对象


据说vc 8.0以上的版本支持NRV优化(http://www.cnitblog.com/luckydmz/archive/2011/10/25/76193.html)

其实RVO要求函数返回匿名对象是有理由的:如果函数返回匿名对象,那么就说明程序员只是利用该匿名对象存储返回值,而并不打算用该匿名对象做其他事情,因此编译器可以将其视为一个允许它做RVO优化的信号,而NRV优化虽然可以对具名返回值做优化,以消除匿名对象的成本,这提高了效率,但有可能是不是程序员的原意.

对于NRV优化的深入了解见《深入探索C++面向对象模型》第二章

4. C++11引入了右值引用与转移语义,其目的不是消除临时对象的构造和析构,而是通过右值引用绑定到右值来延长临时对象生存期,从而直接使用临时对象,这种方法与RVO异曲同工:前者是直接使用临时对象,不再构造新对象;后者避免构造临时对象,将本应构造在临时对象上的内容直接构造到新对象上.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: