[boost] shared_ptr 简介

4 篇文章 0 订阅

翻译来自 : http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm

1. 简介:

 Shared_ptr 模板类用来保存动态申请的对象指针,一般在C++中动态申请使用new表达式. 当最后一个指向对象的share_ptr被销毁或者重置时,对象将会被delete掉. 每一个shared_ptr都实现了拷贝构造以及赋值操作,因此可以在C++标准库的容器中使用.另外,shared_ptr也实现了比较操作符,这使得shared_ptr可以使用在关联类容器(如 map set )中.一般来说,shared_ptr不能用来存放 数组指针. shared_array提供了存放数组指针的功能.

因为shared_ptr的实现使用了引用计数,两个保存有相同对象的shared_ptr相互引用会导致循环引用.比如:

using namespace boost;
class FooB;
class FooA
{
 public:
     shared_ptr<FooB> b_;
};
class FooB
{
public:
      shared_ptr<FooA> a_;
};

int main( void )
{
shared_ptr<FooA> fooa;         // fooa 计数为 1
shared_ptr<FooB> foob;         // foob 计数为 1 
fooa.b_ = foob;                      //  foob 计数为2
foob.a_ = fooa;                      //  fooa 计数为2
 return 1;
}
这样fooa 通过 foob 引用到自己保存的实例. 当 fooa 析构时,只是把引用计数降到1,并不会执行delete操作.  foob也是一样.由此导致内存泄露;可以使用 weak_ptr 来"打破循环".

模板的类型参数T就是shared_ptr对象所指向的类型.shared_ptr以及大部分他的成员函数都对T没有要求, T可以是不完整类型(incomplete type),或者 void.构造函数(constructor),以及 重置(reset) 会对类型T提出要求.这些需求会在下面讲到.

只要T*可以隐式的转换成为U*,shared_ptr<T>就可以隐式的转换成为shared_ptr<U>. 实际上,shared_ptr<T>可以隐式的转换成为 shared_ptr<T const>   shared_ptr<U>(如果U是一个可以访问的基类),以及 shared_ptr<void>.

2. 最佳实践

使用智能指针的一个简单的原则是:总是使用一个具名智能指针变量去保存new的返回值,这样可以有效的防止内存泄露. 每一个出现new 关键字的地方,代码都应有下面类似的格式:    

shared_ptr<T> p(new Y);

当然,也可以使用其他类型的智能指针.T 与 Y有相同的类型. 也可以给Y的构造函数传参.

如果遵循这个原则,那么以后的代码中将不会有显式的delete, try/catch 结构也会减少.

避免使用未命名临时shared_ptr,比如:

void f(shared_ptr<int>, int);
int g();

void ok()
{
    shared_ptr<int> p(new int(2));
    f(p, g());
}

void bad()
{
    f(shared_ptr<int>(new int(2)), g());
}

函数ok 严格的遵守了这个原则,然而函数bad构建了临时的,未命名的shared_ptr对象,从而有可能导致内存泄露.这主要是因为函数参数的计算顺序并不是确定的.在 函数 bad中,

计算顺序有可能是  new int(2)  -->  shared_ptr<int>(new int(2))   -->  g() ,也有可能是 new int(2)  --> g()-->  shared_ptr<int>(new int(2)) ,这时如果函数g()抛出异常,这时shared_ptr还没有构造,因此无法删除 new int(2), 从而引发内存泄露.  可以通过Herb Sutter's treatment 更多的了解这个问题.

上面的这个异常安全问题也可以通过使用 make_shared 或者 allocate_shared 这两个工厂函数来消除.


   
   


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值