问题从这里开始。
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++)
分享到:
相关推荐
详细讲解了Java的值传递和引用传递,英文版,易懂,配图片分析!!
gpio 读写功能void gpio_set_value(int fdint gpio_noint state){unsigned long val;val = (!!state << 31) | gpio_no;if(ioctl(fdGPIOC_OPS&val) < 0){perror("ioctl");}}int gpio_get_...
returnValue是javascript中html的window对象的属性,目的是返回窗口值,下面有个示例,大家可以感受下
returnValue = ParsedString(Definitions.exifCode.ImageDescription); break; case Definitions.exifCode.Make: returnValue = ParsedString(Definitions.exifCode.Make); break; case Definitions.exifCode....
Key-value存储简介
All function arguments in ECMAScript are passed by value
上个礼拜修改测试一个后台管理项目,在测试与各个浏览器兼容性的时候,发现在chrome浏览器下showModalDialog方法显示的并不是模态对话框,就像新打开一个页面一样...而且返回值returnValue也无法返回,一直是undefined
解决androidstudio中出现finished with non-zero exit value 1,或者finished with non-zero exit value 2的问题
Grafna Dashboard 中,... 常规实现没有问题,但对于下拉列表,最终用户一般要求看到的是 text 字段不是 value 字段,查询时则必须按 value 字段 这个问题,在Grafana 中有实现但需要进行设置 本方案解决上述的问题
网页右键ie不支持event.preventDefault和event.returnValue (需要加window) ,需要的朋友可以参考一下
SAP Value Upgrade.pdf
value2
在本篇文章里小编给大家总结了关于Java的call by value和call by reference的相关用法和知识点内容,需要的朋友们学习下。
TreeMap按VALUE排序
公共函数,通过get_keys_from_value(d,val),传入value get key
赠送jar包:spring-data-keyvalue-2.5.5.jar; 赠送原API文档:spring-data-keyvalue-2.5.5-javadoc.jar; 赠送源代码:spring-data-keyvalue-2.5.5-sources.jar; 赠送Maven依赖信息文件:spring-data-keyvalue-...
Check return value double.
MarkDown文档,大家应该都知道,@Value注解可以给类中的非静态变量注入值,但是给静态变量注入值则会有警告,结果是失败的,本文档说明了如何使用@Value注解给类的静态变量赋值
赠送jar包:spring-data-keyvalue-2.3.9.RELEASE.jar; 赠送原API文档:spring-data-keyvalue-2.3.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-keyvalue-2.3.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:...