快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
现在将返回fnresult<T>。为了使这个变化对对调用者透明,fnresult必须可以被隐式的转型为T。

然后为fnresult建立转移语义:无论何时一个fnresult<T>对象被复制,里面包含的T被转移。

类似运算符的常量性和临时性,在mojo::enabled类中为fnresult提供一个转型运算符。

一个mojo化的类(如前例中的String)定义了一个构造函数String( mojo :: fnresult < String > )完成转移。

这个fnresult的定义看起来就像:

namespace mojo
{
 template < class T >
 class fnresult : public T
 {
 public:
  fnresult ( const fnresult& rhs )
   : T ( temporary < T > ( const_cast < fnresult& > ( rhs ) ) )
  {
  }
  explicit fnresult ( T& rhs ) : T ( temporary < T > ( rhs ) )
  {
  }
 };
}

因为fnresult<T>从T继承而来,第一步值得注意,即fnresult<T>转型为T,然后第二个值得注意的就是复制fnresult<T>对象的时候,隐含着它的T子对象(subobject)强制转型为temporary<T>。

正如前面提到的,我们增加一个转型允许返回一个fnresult,最后的版本看起来是这样的:

template < class T > struct enabled
{
 operator temporary < T > ( )
 {
  return temporary < T > ( static_cast < T& > ( *this ) );
 }
 operator constant < T > ( ) const
 {
  return constant < T > ( static_cast < const T& > ( *this ) );
 }
 operator fnresult < T > ( )
 {
  return fnresult < T > ( static_cast < T& > ( *this ) );
 }
 protected:
  enabled ( ) { } // intended to be derived from
  ~enabled ( ) { } // intended to be derived from
};

最后是String的定义:

class String : public mojo :: enabled < String >
{
 //...
public:
 // COPY rhs
 String ( const String& rhs );
 // MOVE tmp.get() into *this
 String ( mojo :: temporary < String > tmp );
 // MOVE res into *this
 String ( mojo :: fnresult < String > res );
};

现在考虑下面的函数:

mojo :: fnresult < String > MakeString()
{
 String result;
//?..
 return result;
}
//...
String dest(MakeString());

在MakeString的return语句和dest的定义之间的路径是:

result -> String :: operator fnresult < String > () -> fnresult < String > (const fnresult < String >& ) -> String :: String ( fnresult < String > )

使用RVO的编译器可以消除调用链中fnresult<String>(const fnresult<String>&)的调用。然而,更重要的是没有函数执行真正的复制,它们都被定义为结果的实际内容平滑的转移到dest。也就是说没有涉及内存分配和复制。

现在,正如所见,有两个,最多三个转移操作。当然,在一定条件和一定类型的情况下,一次复制比三次转移可能更好。还有一个重要的区别,复制也许会失败(抛出异常),而转移永远不会失败。

5 扩展

好的,我们使Mojo工作了,而且对于单独的类相当好。现在怎样将Mojo扩展到组合对象,它们也许包含大量其他的对象,而且他们中的一些已经是mojo化的。

这个任务就是将转移构造函数从类传递到成员。考虑下面的例子,内嵌类String在类Widget中:

class Widget : public mojo::enabled < Widget >
{
 String name_;
public:
 Widget(mojo::temporary< Widget > src) // source is a temporary
  : name

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号