|
|
令人困惑的return by value |
|
|
作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站 |
问题从这里开始。 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++) 
|
|
相关文章:相关软件: |
|