泛型编程-转移构造函数(Generic Programming: Move Constructor)
。考虑下面的C++伪代码:
这个我们虚构的重载构造函数String(temporary String&)在创建一个String临时对象(按照前面的定义)时调用。然后,这个构造函数执行了一个rhs对象转移的构造过程,只是简单的复制指针而不是复制指针指向的内存块。最后,“转移构造函数”复位源指针rhs.data_(恢复为空指针)。使用这个方法,当临时对象被销毁时,delete[]会无害的应用在空指针上[译注:C++保证删除空指针是安全的]。 一个重要的细节是“转移构造”后rhs.length_没有被清0。按照教条主义的观点,这是不正确的,因为data_==0而length_!=0,所以字符串被破坏了。但是,这里有一个很站得住脚的理由,因为rhs的状态没有必要是完整的,只要它可以被安全而正确的销毁就行了。这是因为会被应用在rhs上唯一一个操作就是析构函数,而不是其他的。所以只要rhs可以被安全的销毁,而不用去看是否像一个合法的字符串。 “转移构造函数”对于消除不需要的临时对象复制是一个良好的解决方案。我们只有一个小问题,C++语言中没有temporary关键字。 还应该注意到临时对象的探测不会帮助所有的类。有时,所有的数据直接存储在容器中。考虑:
对这样一个类,实际上复制成本在于逐字节的复制sizeof(FixedMatrix)个字节,而探测临时对象并没有帮助[译注:因为数组不是指针,不能直接交换地址]。 3 过去的解决方案 不必要的复制是C++社区长期存在的问题。有两个努力方向齐头并进,其一是从编码和库编写的角度,另一个是语言定义和编译器编写层面。 语言/编译器观点方面,有返回值优化(Return Value Optimization, RVO)。RVO被C++语言定义所允许[3][译注:但是不是强制性的,而是实现定义的]。基本上,编译器假定通过拷贝构造函数(Copy Constructor)复制返回值。 确切地说,基于这样的假定,因此编译器可以消除不必要的复制。例如,考虑:
聪明的编译器可以将vec的地址作为一个隐藏的参数传递给ReadFile而把result创建在那个地址上。所以上面的源代码生成的代码看起来像这样:
RVO有不同的风格,但要旨是相同的:编译器消除了一次拷贝构造函数的调用,通过简单的在最终目的地上构造函数返回值。 不幸的是,RVO的实现不像看上那样容易。考虑ReadFile稍稍修改后的版本:
************** |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |