博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
令人困惑的return by value (转)
阅读量:2507 次
发布时间:2019-05-11

本文共 1593 字,大约阅读时间需要 5 分钟。

令人困惑的return by value (转)[@more@]

 

问题从这里开始。

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 (指xx)的ctor和dtor,但是作为一个应该把握全局的程序员,我劝你不要太指望它。
首先,它还是了default ctor,这在ARV中是不存在的。
其次,你无法知道编译器是否正在这样做,毕竟对于厂家来说,它有这样的权利不让你知道细节。
再次,编译器就算有这样的能力,但仅仅对一些简单的函数有效,而对于实际来说,函数往往很复杂,
比如具有多个分支返回的函数,编译器就只能叹气了。
还有,在函数开头就声明对象的作法,可不是正宗C++的style,C++一向提倡“只有在必要是才使用”,真正的C++程序员应该牢记这一点。
最后,从C++编译器历史来看,在优化过程中,匿名对象比命名对象更容易消除,你要充分利用它。
答案:
对于这么一个简单的函数,如果你的编译器支持NRV优化,则结果是一样的,否则。。。
而ARV优化总是支持的。
那采用ARV这样做有没有缺点呢?
或许吧,毕竟你要写一堆ctor用于特殊用途了。:)
注:
本文中的例子选自<ide C++ Object Model>>,要感谢Lippman给C++程序员们写了这么一本好书,同样感谢JJhou给中国程序员的翻译。
本文还参考了MEC(More Effective C++)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10748419/viewspace-985009/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10748419/viewspace-985009/

你可能感兴趣的文章
python爬虫---从零开始(五)pyQuery库
查看>>
POJ2236(KB5-A)
查看>>
Centos MySQL数据库迁移详细步骤
查看>>
2初出茅庐--初级篇2.1
查看>>
新建 WinCE7.0 下的 Silverlight 工程
查看>>
腾讯的张小龙是一个怎样的人?
查看>>
jxl写入excel实现数据导出功能
查看>>
linux文件目录类命令|--cp指令
查看>>
.net MVC 404错误解决方法
查看>>
linux系统目录结构
查看>>
git
查看>>
btn按钮之间事件相互调用
查看>>
Entity Framework 4.3.1 级联删除
查看>>
codevs 1163:访问艺术馆
查看>>
冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱
查看>>
并查集
查看>>
sessionStorage
查看>>
代码示例_进程
查看>>
PLSQL数据导入导出问题解决(空表、大字段表、表空间错误等)
查看>>
阻塞、非阻塞的概念和select函数的阻塞功能
查看>>