令人困惑的return by value

以前的文章 专栏收录该内容
3 篇文章 0 订阅

 

问题从这里开始。
class X;
const X operator+( const X& x1, const X& x2 );
X foo()
{
return X(a+b);
}

X foo()
{
X xx(a+b);
return xx;
}
这两个函数,有什么区别?
这个问题牵涉到C++的内部处理,下面是其更通用的模式。
X foo()
{
X xx;
// process
...
return xx;
}
C++如何处理return by value,传统的方法是修改函数原型。
void foo( X& r )
{
X xx;
xx.X(); //ctor
// process
...
r.XX( xx ) // copy ctor
}
这样就把xx的值给返回了,这里有一个xx的临时对象的ctor和dtor。
于是乎。
X obj = foo();
被转化为 
X obj;
foo( obj );
但是,对于程序员来说,是可以进行一些优化的,其方法就是采用ctor返回,
X foo()
{
return X( ... );
}

编译器处理过后,为这样。
void foo( X &r )
{
return r.X(...);
}
看出来了吗?这里少个对象(即上面的xx)的ctor和dtor,效率自然提高。
更进一步,如果这个函数是inline的,则
X obj = foo();
被处理成
X obj;
obj.X(...);
Bingo!!
真的是棒呆了,C++注重的效率得以完全体现。
这种优化我称之为ARV( anonymous return value )优化,:)
然而对于前者NRV( named return value ),我们又该如何呢?
答案是:没有办法,唯一可作的是期待编译器给我们一些帮助。
如果我们的编译器够power的话,那么
X foo()
{
X xx;
// process
...
return xx;
}
可能被处理成:
void foo( X &r )
{
// ctor
r.X();
// process
...
}
在这里,同样没有出现named object(指xx)的ctor和dtor,但是作为一个应该把握全局的程序员,我劝你不要太指望它。
首先,它还是调用了default ctor,这在ARV中是不存在的。
其次,你无法知道编译器是否正在这样做,毕竟对于厂家来说,它有这样的权利不让你知道细节。
再次,编译器就算有这样的能力,但仅仅对一些简单的函数有效,而对于实际编程来说,函数往往很复杂,
比如具有多个分支返回的函数,编译器就只能叹气了。
还有,在函数开头就声明对象的作法,可不是正宗C++的style,C++一向提倡“只有在必要是才使用”,真正的C++程序员应该牢记这一点。
最后,从C++编译器历史来看,在优化过程中,匿名对象比命名对象更容易消除,你要充分利用它。
答案:
对于这么一个简单的函数,如果你的编译器支持NRV优化,则结果是一样的,否则。。。
而ARV优化总是支持的。
那采用ARV这样做有没有缺点呢?
或许吧,毕竟你要写一堆ctor用于特殊用途了。:)
注:
本文中的例子选自<<Inside C++ Object Model>>,要感谢Lippman给C++程序员们写了这么一本好书,同样感谢JJhou给中国程序员的翻译。
本文还参考了MEC(More Effective C++)

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值