c++11中的智能指针

        在C++11中有四种智能指针,auto_ptr,shared-ptr,unique_ptr和weak-ptr,其中auto_ptr有许多不足之处,在C++11中已经建议废弃使用。

1. shared_ptr

    std::shared_ptr智能指针可以通过共享指向对象的所有权,从而实现对对象的动态管理。std::shared_ptr一般不会拥有对象,相反,所有指向对象的std::shared_ptr指针合作起来确保在对象不需要时析构被调用。当最后一个指向对象的std::shared_ptr不再指向该对象时(比如该std::shared_ptr被销毁或者指向别的对象),这个std::shared_ptr会销毁它指向的对象。就像垃圾回收一样,用户自己不用关心被指向对象的生存周期,同时对析构来说,对象的析构时间是确定的。

   一个std::shared_ptr可以通过查询指向对象的引用计数来得到它是否是最后一个指针,引用计数是一个和资源关联的值,它记录了有多少std::shared_ptr指向该资源。std::shared_ptr构造函数中会增加引用计数,析构函数汇总减小引用计数(通常是这样---见下面),拷贝复制操作两者都执行。(假如sp1和sp2指向不同的对象,操作“sp1=sp2;”会修改sp1,指向sp2,结果就是原来sp指向的对象的引用计数减少了,同时sp2指向的对象的引用计数增加了。)当一个std::shared_ptr 指针看到对象的引用计数在指向完减一操作后变为0时,那么没有std::shared_ptr指向该对象了,于是std::shared_ptr将会销毁它。

2. unique_ptr

    通常可以认为std::unique_ptr和原始指针有相同的尺寸,并且对于多数操作(包括解引用),它和原始指针有几乎相同的指令。这意味着你可以在内存和cpu紧张的地方使用它,如果普通的原始指针对你够快够用的话,那么std::unique_ptr几乎也是够用的。

    std::unique_ptr实现了独享所有权的语义。一个非空的std::unique_ptr总是拥有它所指向的资源。转移一个std::unique_ptr将会把所有权也从源指针转移给目标指针(源指针被置空)。拷贝一个std::unique_ptr将不被允许,因为如果你拷贝一个std::unique_ptr,那么拷贝结束后,这两个std::unique_ptr都会指向相同的资源,它们都认为自己拥有这块资源(所以都会企图释放)。因此std::unique_ptr是一个仅能移动(move_only)的类型。当指针析构时,它所拥有的资源也被销毁。默认情况下,资源的析构是伴随着调用std::unique_ptr内部的原始指针的delete操作的。

  std::unique_ptr通常出现两种形式。一种是单个对象(std::unique_ptr),另一种是数组(std::unique_ptr)。标准库提供了一个可以管理new分配数组的unique_ptr版本,为了用一个unique_ptr管理动态数组,我们必须在对象类型后面跟一对方括号。

unique_ptrup(new int[10]);
up.realese();//自动用delete[]销毁其指针。
当unique_ptr指向数组时我们不能使用点和箭头运算符,而是用下标来访问数组中的元素:
for(size_ti=0;i I != 10; ++i)
up[i]=i;
unique_ptru //u指向一个类型为T的动态分配的数组
unique_ptru (p) //u指向内置指针p所指向的动态分配的数组。P必须能转换为类型T*
u[i] //返回位置i的元素


3. weak-ptr

   有时候,我们需要一个灵巧指针可以像std::shared_ptr一样方便,但又不参与管理被指对象的所有权。换句话说,需要一个像std::shared_ptr但又不影响对象引用计数的指针。这类指针会有一个std::shared_ptr没有的问题:被指的对象有可能已经被销毁。一个良好的灵巧指针应该能处理这种情况,通过跟踪什么时候指针会悬浮,比如在被指对象不复存在的时候。这正是std::weak_ptr这类型灵巧指针所能做到的。

  weak_ptr是一种不控制所指向对象生存期的智能指针,它指向一个shared_ptr管理的对象。将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是会被释放。
当我们创建一个weak_ptr时,要用一个shared_ptr来初始化它:

auto p=make_shared_ptr(42);
weak_ptrwp(p); //wp弱共享p,p的引用计数未改变

由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock().此函数检查weak_ptr指向的对象是否存在。如果存在lock则返回一个指向共享对象的shared_ptr,同时该对象的引用计数会增加。
   
if(shared_ptr np= wp.lock())
{
}

      std::weak_ptr可以和std::shared_ptr 一起解决引用计数的循环引用问题。

     具体可参考《std::shared_ptr 和 std::weak_ptr的用法以及引用计数的循环引用问题》



参考文献:

1. c++11 条款19:使用std::shared_ptr来进行共享所有权的资源管理

2. c++11 条款20:使用std::weak_ptr作为一个类似std::share_ptr但却能悬浮的指针

3. c++11 条款18: 使用std::unique_ptr来进行独享所有权的资源管理

4. C++ 智能指针shared-ptr,unique_ptr和weak-ptr

5.      [C++11]_[初级]_[shared_ptr的使用场景]

6.      [C++11]_[初级]_[unique_ptr的使用场景]

7.      [C++11]_[初级]_[weak_ptr的使用场景]

8.    【C++11新特性】 C++11智能指针之unique_ptr

9.    【C++11新特性】 C++11智能指针之shared_ptr

10 .  【C++11新特性】 C++11智能指针之weak_ptr


你可能感兴趣的:(c++11)