令人困惑的return by value

原创 2001年11月09日 13:27:00

 

问题从这里开始。
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++)

MT4提示警示return value&amp;nbs…

问题1:MT4提示警示return value of 'OrderClose' should be checked 代码编程不够严谨的警告,非代码错误。不会影响你EA的运行。新版的MQL4对于订...
  • sjpljr
  • sjpljr
  • 2017年04月14日 10:07
  • 732

CWE-252: 未检查的返回值(Unchecked Return Value)

Translated by:  Apxar Translation From:http://blog.csdn.net/apxar/article/details/23224567 Ess...
  • apxar
  • apxar
  • 2014年04月09日 23:09
  • 1533

springMVC中Unknown return value type: java.lang.Integer(解决)

controller层返回值类型为int,然而报 Unknown return value type: java.lang.Integer
  • menglinjie
  • menglinjie
  • 2017年07月19日 20:41
  • 3295

Warning 534: Ignoring return value of function 'printf

534 Ignoring return value of function 'Symbol' (compare with Location) -- A function that return...
  • m0_38049850
  • m0_38049850
  • 2017年08月03日 11:31
  • 194

ReactNative : ignoring return value of function declared with warn_unused_result attribute

升级到Xcode8后,运行ReactNative 的项目会报错 ignoring return value of function declared with warn_unused_result a...
  • chevins
  • chevins
  • 2016年09月19日 15:23
  • 1908

“Cannot modify the return value of” “because it is not a variable”

编译错误 CS1612 Cannot modify the return value of ‘expression‘ because it is not a variable 无法修改“express...
  • jiangxinyu
  • jiangxinyu
  • 2010年03月09日 15:28
  • 2790

json转换错误:No converter found for return value of type

No converter found for return value of type: class java.util.HashMap最近在搭建一个Spring+springMVC+Mybatis项...
  • gsycwh
  • gsycwh
  • 2017年02月23日 16:52
  • 14887

php5.3 中显示Deprecated: Assigning the return value of new by reference is deprecated in 的解决方法

今天需要将某个网站般去另一台服务器。设置好运行,显示一大堆Deprecated。 Deprecated: Assigning the return value of new by reference ...
  • fdipzone
  • fdipzone
  • 2013年07月17日 21:41
  • 22233

ECShop后台站点地图关于 Deprecated: Assigning the return value of new by reference is deprecated的错误的解决办法

今天对后台系统进行一些简单的操作,当点击  系统设置---站点地图  时发现提示: Deprecated: Assigning the return value of new by reference...
  • fb2058
  • fb2058
  • 2015年01月10日 22:27
  • 3560

java.lang.IllegalArgumentException: No converter found for return value of type

搭建完框架,写了个controller,用postman测试报错,异常信息:java.lang.IllegalArgumentException: No converter found for ret...
  • wudi_neu
  • wudi_neu
  • 2017年04月20日 20:26
  • 484
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:令人困惑的return by value
举报原因:
原因补充:

(最多只允许输入30个字)