闲人草堂

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

今天忙活了半天,结果发现罪魁祸首在使用了auto_ptr。

auto_ptr本身不含有赋值语义,所以在它赋值给别人(例如传参时),实际发生的是控制权的转移。

1 auto_ptr<TYPE> A,B;
2 A = B;

第二行执行完毕后,B的地址为0;

这就是智能指针auto_ptr的缺陷。倘若遇到类似的情况,还是用boost的shared_ptr吧。

另外转载一篇关于auto_ptr的文章,供自己学习。

http://blog.csdn.net/normallife/archive/2011/02/23/6202930.aspx

因为std::auto_ptr是转移语义,而STL容器的元素必须是值语义,也就是拷贝语义的。

比如,STL容器都是以副本的形式来保存元素。
std::vector<int> v;
int a = 1;
v.push_back(a);
v[0]也是值为1的int,但不是a..仅仅是一个副本.a的值也并未被改变.

std::auto_ptr<int> p1(new int);
std::auto_ptr<int> p2 = p1;
p2的构造修改了p1的值,使p1交出了对动态分配的int的引用权.此时p1不再引用动态int.这就是转移语义.

另外,std::auto_ptr为了达到转移语义的要求,只提供了这样的一个拷贝构造函数
auto_ptr(auto_ptr&); 而不是通常情况看到的T(const T&); 这就是一个非值语义的表现.

而std::vector因为对元素类型要求是值语义的,所以必须要求元素类型提供T(const T&)的拷贝构造函数.
它不能用于动态创建的数组。  
可能是因为大部分时候用std::vector就很合适了,所以没有与auto_ptr相对应的auto_array。不过如果真的有特殊需要的话,也很容易仿照 std::auto_ptr写个auto_array。

使用auto_ptr要知道:
1. 智能指针不能共享指向对象的所有权
2. 智能指针不能指向数组。因为其实现中调用的是delete而非delete[]
3. 智能指针不能作为容器类的元素。

posted on 2011-06-09 20:12  闲人草堂  阅读(2717)  评论(0编辑  收藏  举报