快速业务通道

泛型编程-转移构造函数(Generic Programming: Move Constructor)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
****************************************

Wang Tianxing校注:

这个例子并不是很有说服力。里面的三个对象的作用域互不相交,因此还是比较容易使用 RVO 的。难以运用RVO的是这种情况:

vector< String > ReadFile()
{
  vector< String > dumb;
  dumb.push_back( "This file is in error." );
  vector< String > result;
  // ... 填充 result ...
  return error ? dumb : result;
}

******************************************************

现在有不止一个局部变量需要被映射到最后的结果上,他们有好几个。有些是命名的(dumb/result),而另一些是无名的临时对象。无需多说,面对这样的局面,大量优化器会投降并且服从保守的和缺乏效率的方法。

即使想写不导致混淆RVO实现的“直线条”的代码,也会因为听到每个编译器或者编译器版本都有自己探测和应用RVO的规则而失望。一些RVO应用仅仅针对返回无名临时对象的函数,这是最简单的RVO形式。最复杂的RVO应用之一是函数返回值是一个命名的结果,叫做命名返回值优化(Named RVO或NRVO)。

本质上,写程序时要指望可移植的RVO,就要依赖于你的代码的精确写法(在很难定义的“精确”意义下),依赖于月亮的圆缺,依赖于你的鞋的尺码。

但是,别忙,还有很多种情况下RVO无法避免临时对象的拷贝。编译器时常不能应用RVO,即使它很想。考虑稍稍改变后的 ReadFile() 的调用:

vector vec;
vec=ReadFile();

这个改变看上去完全没有恶意,但是却导致了巨大的差异。现在不再调用拷贝构造函数而调用赋值运算符(assignment operator),这是令一个不同的脱缰野马。除非编译器优化技巧完全像是在使用魔法,现在真的可以和RVO吻别了:vector<T>::operator=(const vector<T>&)期望一个vector的常量引用,所以ReadFile会返回一个临时对象,绑定到一个常量引用,复制到vec,然后被废弃。不必要的临时对象又来了!

在编码方面,一个长期被推荐的技术是COW(按需复制,copy-on-write)[4],这是一个基于引用计数的技巧。

COW有几个优点,其中之一是探测和消除了不必要的复制。例如,函数返回时,返回的对象的引用计数是1。然后复制的时候,引用计数增加到2。最后,销毁临时对象的时候,引用计数回到1,引用指向的目的地仅仅是数据的所有者。实际上没有复制动作发生。

不幸的是,引用计数在多线程安全性方面有大量的缺陷,增加自己的开销和大量隐藏的陷阱[4]。COW是如此之笨拙,因此,虽然它有很多优点,最近的STL实现都没有为std::string使用引用计数,尽管实际上std::string的接口有目的设计为支持引用计数!

已经开发了几个实现“不可复制”对象的办法,auto_ptr是最精炼的一个。auto_ptr是容易正确使用的,但是不幸的是,刚好也容易不正确的使用。本文的讨论的解决方法扩充了定义auto_ptr中使用的技术。

4 Mojo

Mojo(联合对象转移,Move of Joint Objects)是一项编码技术,又是一个消除不必要的临时对象复制的小框架。Mojo通过辨别临时对象和合法的“非临时”的对象而得以工作。

4.1 传递函数参数

Mojo引发了一个有趣的分析,即函数参数传递约定的调查。Mojo之前的一般建议是:

[规则1]如果函数试图改变参数(也就是作为副作用),则把参数作为非常量对象的指针或者引用传递。例如:

void Transmogrify(Widget& toChange);
void Increment(int* pToBump);

[规则2]如果函数不修改它的参数而且参数是基本数据类型,则按照值传递参数。例如:

double Cube(double value);

[规则3]否则,参数是用户自定义类型(或者模板的类型参数)而且一定不变,则作为常量引用传递参数。例如:

String& String

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号