boost 内存管理

1.      Boost提供六种智能指针:scoped_ptr,scoped_array,shared_ptr,shared_array,weak_ptr,intrusive_ptr,他们都是轻量级的对象,速度和原始指针相差无几,对所有类型T只需要:类型T的析构函数都不能抛异常。

2.      scoped_ptr:类似于auto_ptr的智能指针,但是它的所有权更加严格,不能转让,一但它获得对象的管理权,你就无法从那里取回来。并且只在本作用域里使用,不希望转让。提供的操作:

1)     reset(T* p = 0):重置scoped_ptr,删除原来保存的指针,再保存新的指针值p。一般情况下reset不应该被调用,因为资源一致应该由scoped_ptr自己自动管理。

2)     scoped_ptr不支持比较操作,operator==和operator!=两个操作符都声明为私有。但是支持在bool语境中自动转换成bool值(如if条件表达式),用来测试scoped_ptr是否持有一个有效的指针(非空)。

3)     成员函数swap可以交换两个scoped_ptr保存的原始指针,也可以被boost::swap所利用。

4)     成员函数get,返回scoped_ptr内部保存的原始指针。但是注意不要对这个返回的原始指针做delete操作,否则scoped_ptr析构时会对已经删除的指针再进行删除操作。

5)     与auto_ptr的区别:scoped_ptr的用法与auto_ptr几乎一样,大多数情况下二者可以实现替换,也可以从auto_ptr获得指针管理权(同时auto_ptr失去管理权)。二者同样不能用作容器的元素,但原因不一样:auto_ptr是因为转移语意,scoped_ptr因为不支持拷贝和赋值,不符合容器元素类型的要求。

3.      scoped_array(动态数组应该使用std::vector,它提供了比scoped_array更多的灵活性,而只付出了很小的代价,不推荐使用scoped_array):很像scoped_ptr,他包装了new[]操作符在堆上分配的动态数组。接口几乎与scoped_ptr是相同的,主要特点如下:

1)     构造函数接受的指针p必须是new[]的结果,而不能是new表达式的结果;

2)     没有*, ->操作符重载,因为scoped_ptr持有的不是一个普通指针;

3)     析构函数使用delete[]释放资源,而不是delete;

4)     提供operator[]操作符重载,像普通数组一样用下标访问元素;

5)     没有begin(), end()等类似于容器的迭代器操作函数。

4.      shared_ptr实现的是引用计数型智能指针。提供的操作:

1)     重载了*, ->操作符,提供隐式bool类型转换以判断指针的有效性,get()可以得到原始指针,并且没有提供指针算术操作;

2)     多种形式的构造函数;(其中还可以定制删除器);

3)     reset将引用计数器减1,同时管理参数中的另一个指针;

4)     两个专门的函数检查引用计数:unique()在shared_ptr是指针的唯一所有者返回true和use_count()返回当前指针的引用计数。use_count()应该仅仅用于测试或调试,不提供高效操作;

5)     支持类型转换:static_pointer_cast,const_pointer_cast,dynamic_pointer_cast,都是返回转型后的shared_ptr;

6)     支持流输出符operator<<,输出内部指针值。

5.      <boost/make_shared.hpp>提供了一个自由工厂函数make_shared<T>(),来消除显式new调用:shared_ptr<string>sp = make_shared<string>(“hello”);

6.      shared_ptr应用于标准容器,一种是将容器作为shared_ptr管理的对象,如shared_ptr<list<T>>,使容器被安全地共享;另一种用法是将shared_ptr作为容器的元素,如vector<shared_ptr<T>  >,shared_ptr支持拷贝和比较操作,符合标准容器对元素的要求。

7.      shared_ptr可以指定删除器d,告诉shared_ptr在析构时不是使用delete来操作指针p,而是用d来操作,即把deletep换成d(p)。对删除器的要求是必须是可拷贝的,行为必须也像delete那样,不能抛出异常。

8.      shared_array类似于shared_ptr,包装了new[]操作符在堆上分配的动态数组。shared_array多数情况下可以用shared_ptr<std::vector<>>或std::vector<shared_ptr>来代替。

9.      weak_ptr是为配合shared_ptr而引入的一种智能指针,不具有普通指针的行为,最大的作用就是协助shared_ptr工作,像旁观者那样观测资源的使用情况。特点:

1)     weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加;析构也不会导致引用引用计数减少,它只是一个静静的观察者;

2)     use_count和expired观测资源的引用计数,expired等价于use_count()== 0,表示观测资源已经不复存在;

3)     没有重载operator*和->,这是特意的,不共享指针,不能操作资源,这也是“弱”的原因;

4)     成员函数lock()从观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源。当expired()== true时,lock()函数将返回一个存储空指针的shared_ptr。

10.  获得this的shared_ptr:weak_ptr的一个重要用途就是获得this指针的shared_ptr,使对象自己能够生产shared_ptr管理自己;对象使用weak_ptr观测this指针,这并不影响引用计数,在需要的时候就调用lock()函数,返回一个符合要求的shared_ptr共外界使用。这个解决方案被实现为一个惯用法,在头文件<boost/enable_shared_from_this.hpp>定义了一个助手类enable_shared_from_this<T>,它的声明摘要如下:

template<classT>
class enable_shared_from_this
{
public:
 shared_ptr<T> shared_from_this();
}

使用的时候只需要让像被shared_ptr管理的类从它继承即可,成员函数shared_from_this()会返回this的shared_ptr.例如:

#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost;
using namespace std;
class self_shared: public enable_shared_from_this<self_shared>
{
public:
 self_shared(int n):x(n){}
 int x;
 void print()
 {cout<<" self_shared:"<<x<<endl;}
};
int _tmain(int argc, _TCHAR* argv[])
{
 shared_ptr<self_shared> sp = make_shared<self_shared>(314);
 sp->print();
 shared_ptr<self_shared> p = sp->shared_from_this();
 p->x = 1000;
 p->print();
 return 0;
}

注意:千万不能从一个普通对象(非shared_ptr)使用shared_from_this()获去shared_ptr,例如:

self_sharedss;
shared_ptr<self_shared> p = ss.shared_from_this();//错误!
在运行时会导致shared_ptr析构时企图删除一个栈上分配的对象,发生未定义行为。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值