快速业务通道

不要把auto_ptr放入容器

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

本来没有打算自己翻译Effective STL的,怕影响大家情绪:),只是发现有些条款在网络上找不到,只好自己翻译了。--Winter

坦白的讲,这个条款不应加入本书,因为包含atuo_ptr的容器(COAPs)本来在STL中就是禁止的。就算你这么用了,编译器也不会编译你的代码。而标准委员会也没有解释为什么不能这样。对于COAPs我应该什么都不用说的,因为你的编译器应该替你做好了一切工作,所有这种类似的代码都不应该被编译。

可惜的是,许多程序员使用的STL版本并不拒绝COAPS,更要命的是,许多程序员发现这个曾经非常简单直接用于减少内存泄漏的自动指针经常伴随指针容器。因此虽然STL可能并不支持,许多程序员还是去试图使用COAPs。

我来讲解COAPs到底有什么缺点,以至于标准委员会都明确禁止它。好了,马上开始。我讲一个不足点,不用auto_ptr的相关知识,甚至不用任何STL容器的知识你都能明白:COAPs不灵活(portable)。他们到底能怎样?C++标准中就禁止它了,好一点的STL平台将都不容许它的存在,这些都是有原因的,我会慢慢告诉你。当前的STL平台没有禁止COAPs,你会发现存在COAPs时,代码比以前更加不灵活了。只要你很看中灵活性(当然应该如此),你就应该拒绝使用COAPs。

但是可能你并不关心灵活性,如果真是这样,请允许我友善的提醒你,就是拷贝atuo_ptr的独特的(也可以说成是奇怪的)定义。

当你拷贝一个auto_ptr,被auto_ptr所指的对象的所有权已经转移到了新的auto_ptr中去了,原有的auto_ptr被设置为NULL。你理解的没有错:拷贝一个auto_ptr,将会改变auto_ptr本身的值。

auto_ptr<Widget> pw1 (new Widget);   // pwl1points to a Widget
auto_ptr<Widget> pw2(pw1);  // pw2 points to pw1''s Widget;
  // pw1 is set to NULL. (Ownership
  // of the Widget is transferred
  //from pw1 to pw2.)
pw1 = pw2;  // pw1 now points to the Widget
  // again; pw2 is set to NULL

这可能很有趣,但当然是不正常的,你作为一个STL的使用者,要你小心使用的原因是,auto_ptr会导致一些莫名其妙的结果。举例来说,详细看看下面看似“清白无辜”的代码,这些代码先产生一个包含atuo_ptr<Widget>的vector,然后通过比较指向Widgets的指针来对vector进行排序:

bool widgetAPCompare(const auto_ptr<Widget>& lhs,
const auto_ptr<Widget>& rhs) {
   return *lhs < *rhs; //for this example, assume that
   }   // operator< exists for Widgets
vector<auto_ptr<Widget> > widgets; // create a vector and then fill it
  //with auto_ptrs to Widgets;
  // remember that this should
  //not compile!
sort(widgets.begin(), widgets.end(), // sort the vector
  widgetAPCompare);

不管这些代码看起来有多么合理,这个运行结果肯定是不合理的。最简单的,排序的时候,widgets中会有一个或者多个auto_ptrs的值被改为NULL。vector本身的排序操作,却改变了容器本身的值。把这其中的原理弄明白还是比较值得的,我们来推断一下:

它可能是因为sort算法的实现(一个公用的方法,并被证明过的),在快速排序算法过程中不得不使用一些临时变量。我们并不关心快速排序算法的具体实现,但其基本概念是,排序一个容器中的元素,必定会有某个元素用来作为“pivot element”,然会递归比较一个元素比这个pivot element大于小于或等于进行排序。在排序内部,实现方法可能像这样:

template<class RandomAccesslterator,  // this declaration for
  class Compare>   // sort is copied straight
void sort

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