boost源码剖析3----内存管理shared_ptr

来源:互联网 发布:黄子华 知乎 编辑:程序博客网 时间:2024/05/24 05:03

        Shared_ptr类末班可以指向动态内存分配的对象,支持比较操作,可以搭配STL关联式容器,可以说是最智能的一种指针了,它与scoped_ptr一样是包装了new分配的动态对象,与scoped_ptr不同的是Shared_ptr引入了计数型的智能指针,可以被自由的赋值和拷贝,当引用为0时,才删除引用指向的对象。它的行为最接近原始指针,因此比auto_ptr和scoped_ptr使用范围更广。

shared的本身代码比较复杂,我把它经过一番休整,提取里面的关键部分,摘要如下:

template<class T> class shared_ptr{private:    typedef shared_ptr<T> this_type;public:    typedef T element_type;    typedef T value_type;    typedef T * pointer;    typedef typename boost::detail::shared_ptr_traits<T>::reference reference;//特性萃取    shared_ptr(): px(0), pn()// never throws in 1.30+ 默认构造函数,指针为空,引用计数为0    {    }explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete explicit表示只能显示构造对象,带    {//构造一个拥有指针 p 的 shared_ptr        boost::detail::sp_enable_shared_from_this( this, p, p );    }template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)//构造一个拥有指针 p 和删除器 d 的 shared_ptr。//下面那个构造函数用 a 的一个拷贝分配内存    {        boost::detail::sp_enable_shared_from_this( this, p, p );    }template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )    {        boost::detail::sp_enable_shared_from_this( this, p, p );    }shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws    {//如果 r 为 empty,构造一个 empty shared_ptr,否则,//构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr    }    template<class Y>    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw    {//构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr,并存储 r 中所存储指针的一个拷贝// it is now safe to copy r.px, as pn(r.pn) did not throw        px = r.px;    }template<class Y>    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()    {//构造一个 shared_ptr,就像存储了一个 r.release() 的返回值的拷贝        Y * tmp = r.get();   //auto_ptr失去指针的管理权        pn = boost::detail::shared_count(r);        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );    }void set();template<class Y> void reset(Y *p);bool unique() const;            //判断是否为指针的唯一所有者long use_count() const;//当前指针引用计数private:    template<class Y> friend class shared_ptr;    template<class Y> friend class weak_ptr;#endif    T * px;                     // contained pointer    boost::detail::shared_count pn;    // reference counter};  // shared_ptr
用法1:

#include <boost\smart_ptr.hpp>#include <string>using namespace std;using namespace boost;int main(){boost::shared_ptr<int> a(new int(10));assert(a.unique());boost::shared_ptr<int> b = a;cout<<b.use_count()<<endl;//2//a[3] = 15;*a = 4;cout<<*a<<endl;//4b.reset();cout<<a.use_count()<<endl;//1return 0;}
用法2:工厂函数

智能指针的作用在于消除new和delete的显示调用,但是在上面的例子里为了构造一个堆内存还是调用了new,前面说过,显示的调用delete或new可能会引发一系列问题,那么怎么消除new和delete的显示调用呢,那就要使用到工厂函数make_shared。它的名字模仿了STL中的make_pair,声明如下:template<class T, class ... args> shared_ptr<T>make_ shared(Args ... args);最多可以接受10个参数,它创建一个shared_ptr的对象并返回。下面例子说明它的用法:

#include <boost\smart_ptr.hpp>#include <string>#include <vector>using namespace std;using namespace boost;int main(){boost::shared_ptr<int> pt2 = boost::make_shared<int>(int(10));boost::shared_ptr<vector<string> > str = boost::make_shared<vector<string> >(10,"test");return 0;}
用法3:桥接模式

桥接模式是一种结构设计模式,它把类的具体实现 细节对用户隐藏起来,达到类之间最小的耦合关系。例子如下:

#include <boost\smart_ptr.hpp>#include <string>using namespace std;using namespace boost;class test{private:class hide;boost::shared_ptr<hide> p1;public:test():p1(new hide){}void print(){p1->print();}};class test::hide{public:hide::hide(){}void print(){cout<<"hide print"<<endl;}};int main(){test a;a.print();}
用法4:应用与标准容器

int main(){typedef vector<boost::shared_ptr<int> > vs;vs v(10);int i =0;for(vs::iterator pos = v.begin(); pos!=v.end();pos++){(*pos) = boost::make_shared<int>(++i);cout<<**pos<<endl;}boost::shared_ptr<int> p =v[9];*p =88;cout<<*v[9]<<endl;return 0;}
注意vector存储的是shared_ptr,在对itertor解引用时得到shared_ptr,在解引用得到值。

用法5:定制删除器

假设有一个类socket,

class socket{private:int *p;public:socket(){}void close(){delete p;//其它操作}}

有一个对象socket s,那我们可以这样调用shared_ptr<socket> p(s,close),当离开作用域时,它会自动调用close释放资源。




原创粉丝点击