JasonJian

寻得本性,自得其乐

导航

【C++11】智能指针.md

C++11中有哪几种智能指针

  • auto_ptr
  • shared_ptr
  • scope_ptr

简单介绍auto_ptr

  • auto_ptr是一个可以根据其自己指向的内容自动确定类型的指针
  • auto_ptr在aos代码中用得比较多
  • 使用auto_ptr需要包含#include <memory>头文件

简单介绍shared_ptr

  • 通过指针保持对某个对象共享拥有权的智能指针。若干个shared_ptr对象可以拥有同一个对象,最后一个指向该对象的shared_ptr被销毁或者重置时,该对象被销毁。销毁该对象时使用的是delete 表达式,或者是在构造shared_ptr时传入的自定义删除器。

使用auto_ptr需要注意的地方

  • auto_ptr 类可以用于管理由 new 分配的单个对象,但是无法管理动态分配的数组(我们通常不会使用数组,而是使用 vector 代替数组)。
  • auto_ptr 在拷贝和赋值的时候有不寻常的行为,因此 auto_ptrs 不能被保存在 stl 的容器中。当 auto_ptr 离开了自己的作用域或者被销毁,由 auto_ptr 管理的对象也会被销毁。

复用一个智能指针

  • 使用auto_ptr的reset()函数来重置auto_ptr使之拥有另一个对象。
  • 如果这个auto_ptr已经拥有了一个对象,那么,它会先删除已经拥有的对象,因此调用reset()就如同销毁这个auto_ptr,然后新建一个并拥有一个新对象:
 void h()
 {
     auto_ptr<T> pt( new T(1) );
    // 即pt会首先delete pt目前指向的地址(new T(1)得到的地址),然后再指向new T(2)分配的地址
     pt.reset( new T(2) );
 } 

进一步了解shared_ptr:

  • boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
  • shared_ptr是线程安全的,这在多线程程序中非常重要
  • shared_ptr可以使用在stl容器中
  • boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
  • 避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
  • shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
  • 不要构造一个临时的shared_ptr作为函数的参数。

一段可能导致内存泄露的shared_ptr使用代码

void test()
{
    foo(boost::shared_ptr<implementation>(new implementation()),g());
}
// 上面的代码如何造成了内存泄露

正确的用法为:

void test()
{
    boost::shared_ptr<implementation> sp(new implementation());
    foo(sp,g());
}

shared_ptr实现说明

在典型的实现中,std::shared_ptr 只保存两个指针:
指向被管理对象的指针
指向控制块(control block)的指针
控制块是一个动态分配的对象,其中包含:
指向被管理对象的指针或被管理对象本身
删除器
分配器(allocator)
拥有被管理对象的 shared_ptr 的数量
引用被管理对象的 weak_ptr 的数量
通过 std::make_shared 和 std::allocate_shared 创建 shared_ptr 时,控制块将被管理对象本身作为其数据成员;而通过构造函数创建 shared_ptr 时则保存指针。
shared_ptr 持有的指针是通过 get() 返回的;而控制块所持有的指针/对象则是最终引用计数归零时会被删除的那个。两者并不一定相等。
shared_ptr 的析构函数会将控制块中的 shared_ptr 计数器减一,如果减至零,控制块就会调用被管理对象的析构函数。但控制块本身直到 std::weak_ptr 计数器同样归零时才会释放。

posted on 2014-08-03 18:20  JasonJian  阅读(301)  评论(0编辑  收藏  举报