本文共 1593 字,大约阅读时间需要 5 分钟。
问题从这里开始。
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 ){ // ctorr.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/