快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
。考虑下面的C++伪代码:

class String
{
  //...同前...
  String(temporary String& rhs)
    : data_(rhs.data_), length_(rhs.length_)
  {
    //复位源字符串使它可以被销毁
    //因为临时对象的析构函数仍然要执行
    rhs.data_ =0;
  }
  //...
}

这个我们虚构的重载构造函数String(temporary String&)在创建一个String临时对象(按照前面的定义)时调用。然后,这个构造函数执行了一个rhs对象转移的构造过程,只是简单的复制指针而不是复制指针指向的内存块。最后,“转移构造函数”复位源指针rhs.data_(恢复为空指针)。使用这个方法,当临时对象被销毁时,delete[]会无害的应用在空指针上[译注:C++保证删除空指针是安全的]。

一个重要的细节是“转移构造”后rhs.length_没有被清0。按照教条主义的观点,这是不正确的,因为data_==0而length_!=0,所以字符串被破坏了。但是,这里有一个很站得住脚的理由,因为rhs的状态没有必要是完整的,只要它可以被安全而正确的销毁就行了。这是因为会被应用在rhs上唯一一个操作就是析构函数,而不是其他的。所以只要rhs可以被安全的销毁,而不用去看是否像一个合法的字符串。

“转移构造函数”对于消除不需要的临时对象复制是一个良好的解决方案。我们只有一个小问题,C++语言中没有temporary关键字。

还应该注意到临时对象的探测不会帮助所有的类。有时,所有的数据直接存储在容器中。考虑:

class FixedMatrix
{
  double data_[256][256];
public:
  //...操作...
};

对这样一个类,实际上复制成本在于逐字节的复制sizeof(FixedMatrix)个字节,而探测临时对象并没有帮助[译注:因为数组不是指针,不能直接交换地址]。

3 过去的解决方案

不必要的复制是C++社区长期存在的问题。有两个努力方向齐头并进,其一是从编码和库编写的角度,另一个是语言定义和编译器编写层面。

语言/编译器观点方面,有返回值优化(Return Value Optimization, RVO)。RVO被C++语言定义所允许[3][译注:但是不是强制性的,而是实现定义的]。基本上,编译器假定通过拷贝构造函数(Copy Constructor)复制返回值。

确切地说,基于这样的假定,因此编译器可以消除不必要的复制。例如,考虑:

vector< String > ReadFile()
{
  vector< String > result;
  //...填充result...
  return result;
}
vector< String > vec=ReadFile();

聪明的编译器可以将vec的地址作为一个隐藏的参数传递给ReadFile而把result创建在那个地址上。所以上面的源代码生成的代码看起来像这样:

void ReadFile(void* __dest)
{
  //使用placement new在dest地址创建vector
  vector< String >& result=
    *new(__dest) vector< String >;
  //...填充result...
}
//假设有合适的字节对齐
char __buf[sizeof(vector< String >)];
ReadFile(__buf);
vector< String >& vec=
  *reinterpret_cast < vector< String >* >(__buf);

RVO有不同的风格,但要旨是相同的:编译器消除了一次拷贝构造函数的调用,通过简单的在最终目的地上构造函数返回值。

不幸的是,RVO的实现不像看上那样容易。考虑ReadFile稍稍修改后的版本:

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

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

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

分享到: 更多
h/39453.htm" title="iBATIS 3内的新特性:将iBATIS用作应用程序内的一种持久框架 - 编程入门网" target="_blank">iBATIS 3内的新特性:将iBATIS用作应用程序内的一种持久框架 - 编程入门网
  • Photoshop绘制高光水晶质感水晶苹果
  • 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号