注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

罗维的博客

{ 关注机器学习、计算广告、自然语言处理、大规模数据处理等 }

 
 
 
 
 

日志

 
 

[C++] 为什么不要在STL容器中存储auto_ptr对象  

2011-05-28 23:29:50|  分类: 程序设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
大多数C++ 程序员都知道不要把auto_ptr 对象作为STL容器元素来使用。但是很少有人知道到底是为什么。C++标准如是说:“STL元素必须具备拷贝构造和可赋值……”,其意思是说对象可以进行 安全的赋值操作,可以将一个对象拷贝到另一个对象,从而获得两个独立的,逻辑上相同的拷贝。尤其是当一个对象被拷贝到目标对象后,原来的对象不会改变。但 auto_ptr 却不然,用 auto_ptr 进行赋值和拷贝操作不仅会改变目标拷贝,而且还明显地改变原来的对象。明确地说,就是原来对象将指针的物主身份转换成目标对象,与此同时,原来对象中的指针变成了NULL。想一下下面这段代码会发生什么:

  =================================================================

class
 Foo{};
  vector  
< auto_ptr <Foo> > vf; // 声明 auto_ptr类型向量元素
  
// 填写 vf
  int g()
  {
    auto_ptr 
<Foo> temp = vf[0]; // vf[0] 变成 null
  }

  =================================================================

      当temp 被初始化,成员vf[0]被改变:其指针变成null。任何对该元素的使用企图将导致运行时崩溃。任何时候,只要拷贝容器元素,这种情况都有可能发生。记住,即使代码没有进行显式的拷贝或赋值操作,许多算法如:swap()、random_shuffle()、 sort()……会创建一个或多个容器元素的临时拷贝。此外,某些容器的成员函数可能会创建一个或多个元素的临时拷贝。从而使原来的对象变成无效对象。任何并发的对容器元素的操作企图因此而变成了不明确的或者说未定义的行为。
     正是由于auto_ptr在发生对象拷贝时,原来的元素的内容均会变为NULL,这时对原来元素的访问都将是危险的。
     个别Visual C++ 程序员说他们在STL容器中使用auto_ptr时从来没有遇到过任何问题。告诉你吧,这是暂时的,因为Visual C++ (所有版本)的 auto_ptr 实现都将过期,所依赖的规范都将作废。只要微软决定向最新的ANSI/ISO C++ 标准靠拢(这已经是大势所趋),并对其标准库作相应修改。那么在STL容器中使用 auto_ptr 的代码将出现严重故障。
所以,大家一定不要在STL容器中使用 auto_ptr。不管是空指针,还是其它代替auto_ptr 的智能指针类(如Boost.org提供的那些类)都应该如此。
  评论这张
 
阅读(1032)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017