C++中的智能指针——auto_ptr, unique_ptr, shared_ptr和weak_ptr

http://www.cnblogs.com/lanxuezaipiao/p/4132096.html

STL一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr和weak_ptr


所有的智能指针类都有一个explicit构造函数,以指针作为参数。比如auto_ptr的类模板原型为:


templet<class T>
class auto_ptr {
  explicit auto_ptr(X* p = 0) ; 
  ...
};


因此不能自动将指针转换为智能指针对象,必须显式调用:


shared_ptr<double> pd; 
double *p_reg = new double;
pd = p_reg;                               // not allowed (implicit conversion)
pd = shared_ptr<double>(p_reg);           // allowed (explicit conversion)
shared_ptr<double> pshared = p_reg;       // not allowed (implicit conversion)
shared_ptr<double> pshared(p_reg);        // allowed (explicit conversion)

3. 为什么摒弃auto_ptr?

如果有一个auto_ptr A指向一个对象,另一个auto_ptr B; B = A;那么当A,B过期时,便会出现一个问题,A和B都会释放堆对象是是不能接受的,因为程序将试图删除同一个对象两次。

要避免这种问题,方法有多种:

  • 定义陚值运算符,使之执行深复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本,缺点是浪费空间,所以智能指针都未采用此方案。
  • 建立所有权(ownership)概念。对于特定的对象,只能有一个智能指针可拥有,这样只有拥有对象的智能指针的构造函数会删除该对象。然后让赋值操作转让所有权。这就是用于auto_ptr和uniqiie_ptr 的策略,但unique_ptr的策略更严格。
  • 创建智能更高的指针,跟踪引用特定对象的智能指针数。这称为引用计数。例如,赋值时,计数将加1,而指针过期时,计数将减1,。当减为0时才调用delete。这是shared_ptr采用的策略。
<span style="font-size:18px;">auto_ptr<string> pwin;
pwin = A;
A将失去所有权,将对象的所有权转移给pwin,A变为NULL</span>


C++11中的unique_ptrauto_ptr的替代品,它与auto_ptr一样拥有唯一拥有权的特性,与auto_ptr不一样的是,unique_ptr是没有复制构造函数的,这就防止了一些“悄悄地”丢失所有权的问题发生

  • 使用unique_ptr时编译出错,与auto_ptr一样,unique_ptr也采用所有权模型,但在使用unique_ptr时,程序不会等到运行阶段崩溃,而在编译器因下述代码行出现错误
  • auto_ptr是等到运行时才发现错误。
  • 总之,党程序试图将一个 unique_ptr 赋值给另一个时,如果源 unique_ptr 是个临时右值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做

使用auto_ptr时,需要注意以下几点:

  • auto_ptr不能共享所有权;
  • auto_ptr不能指向数组;对于这点,我认为如果数组中存放的是POD类型时,或者含有trivial destructor时,是可以指向数组的;
  • auto_ptr不能作为容器的成员;C++标准已经明确禁止这么做了,否则可能会遇到不可预见的问题,如果想让自己死的更惨一点,你可以这么做,没有问题。



http://www.jellythink.com/archives/684

http://www.jellythink.com/archives/673



猜你喜欢

转载自blog.csdn.net/yyf_it/article/details/52303620