zoukankan      html  css  js  c++  java
  • Smart_ptr库

        除了标准库提供的智能指针std::auto_ptr外,boost中存在六个智能指针:scoped_ptr,shared_ptr,intrusive_ptr,weak_ptr和scoped_array,shared_array。

       相比于std::auto_ptr不能用作STL容器的元素,Boost的智能指针则填补了这个空白。


    --何时需要智能指针

    a).资源的共享所有权中:两个或多个对象必须同时使用第三个对象的情况。

    b).编写异常安全的代码时:在异常抛出时没有资源泄漏,并保证程序状态的一致性。

    c).避免常见错误,例如资源泄漏时:比如忘记调用delete函数,或没有正确调用delete[]等。


    --智能指针scoped_ptr:

    a).头文件:#include <boost/scoped_ptr.hpp>
    b).说明:

    拥有类似于std::auto_ptr的特征,但不同在于不会像std::auto_ptr那样转移所有权。

    拥有所指向资源的所有权,并且永远不会意外地放弃所有权。

    c).提纲:
    namespace boost{
    template<typename T>
    class scoped_ptr:noncopyable
    {
    public:
    explicit scoped_ptr(T * p=0);
    ~scoped_ptr();
    void reset(T * p=0);//先delete掉原资源,在关联新资源
    T& operator*() const;//这两个操作是scoped_ptr能够像裸指针一样使用
    T* operator->() const;//这两个操作是scoped_ptr能够像裸指针一样使用
    T* get() const;//可以用于判断是否绑定的是空指针,不过常用方法是直接使用if(p)想过等同于if(p.get())。
    void swap(scoped_ptr & b);
    };//class scoped_ptr
    template<typename T>
    void swap(scoped_ptr<T> & a,scoped_ptr<T> & b);

    d).小结:scoped_ptr给我的感觉主要有两个功能:

    利用析构函数自动调用delete函数;

    利用scoped_ptr的生命期来管理所指向资源的生命期--即在socped_ptr对象生命期结束是自动调用析构函数。

    --智能指针scoped_array

    a).小结:

    头文件:#include <boost/scoped_array.hpp>

    其与scoped_ptr的关系相当于new和new[]的关系,用于管理动态数组,在析构函数中调用delete[]函数。

    推荐使用std::vector。


    --智能指针shared_ptr:

    a).头文件:#include <boost/shared_ptr.hpp>
    b).说明:

    适用的情况是多个对象共享一个指针的时候,就不用管理什么时候delete指针了。

    关键点在名字中的shared,通过在内部使用一个计数器来实现多个对象共享一个指针。

    c).提纲:
    namesapce boost{

    template<typename T>

    class shared_ptr{

    public:

    template<class Y>

    explicit shared_ptr(Y * p);

    template<class Y,class D>

    shared_ptr(Y * p,D d);

    ~shared_ptr();

    shared_ptr(const shared_ptr & r);

    template<class Y>

    explicit shared_ptr(const weak_ptr<Y> & r);

    template<class Y>

    explicti shared_ptr(std::auto_ptr<Y> & r);

    shared_ptr& operator=(const shared_ptr & r);

    void reset(); //停止对指针的共享,应用计数将减一

    T& operator*() const;

    T* operator->() const;

    T* get() const;

    bool unique() const; //判断是否是指针的唯一拥有者

    long use_count() const; //返回引用计数器的值

    operator unspecified-bool-type() const;

    void swap(shared_ptr<T> & b);

    };

    template<class T,class U>

    shared_ptr<T> static_pointer_cast(const shared_ptr<U> & r); //引用计数安全的转换
    } //namespace boost

    d).小结:

    使用情况的理解是所有指针都使用智能指针,因为如果有直接使用裸指针的情况下智能指针还是不能记录的。

    内部原理猜测:

    应该是在初次使用的时候建立一个共享计数器,

    以后没增加一个智能指针来引用就把指针和共享计数器一起拷贝过去,

    智能指针的接口能根据情况调用计数器--因为计数器是共享的所以所有持有计数器的智能指针都接收到最新消息。

    计数器应该是线程安全的,但递减为零时就调用delete函数。

    shared_ptr还可以提供删除工具而不掉用delete函数。


    --enable_shared_from_this:

    头文件:#include <boost/enable_shared_from_this.hpp>

    小结:

    使用情况是需要将this转化为shared_ptr的时候。

    使用方法:

    通过继承enbale_shared_from_this<被继承的类类型>就可以使用方法shared_from_this()来获得this的shared_ptr。


    --shared_array:

    头文件:#include <boost/shred_array.hpp>

    小结:

    主要是对指针数组的智能指针,不过推荐使用std::vector。


    --intrusive_ptr:

    头文件:#include <boost/intrusive_ptr.hpp>

    小结:

    这个智能指针是对shared_ptr的扩展,shared_ptr是内部维护引用计数器(非侵入式)的,intrusive_ptr是侵入式的--即自己提供引用计数器的管理。

    自己提供引用计数器主要是提供两个需要增减引用计数器时给intrusive_ptr调用的特定的函数。

    关于这两个函数也有一定的技巧。


    --weak_ptr:

    头文件:#inlcude <boost/weak_ptr.hpp>

    小结:

    weak_ptr对于shared_ptr来说是一个重要的伙伴。

    需要weak_ptr的情况:需要打破循环依赖;需要使用共享资源而不是共享所有权;避免悬空指针。


    总结:

    个人感觉智能库的核心还是shared_ptr,不过每一个都适用不同的情况,但shared_ptr使用更广泛一些。

    而且智能指针也可以作为一种内存管理的方法和学习的好的例子。

  • 相关阅读:
    CodeForces gym Nasta Rabbara lct
    bzoj 4025 二分图 lct
    CodeForces 785E Anton and Permutation
    bzoj 3669 魔法森林
    模板汇总——快读 fread
    bzoj2049 Cave 洞穴勘测 lct
    bzoj 2002 弹飞绵羊 lct裸题
    HDU 6394 Tree 分块 || lct
    HDU 6364 Ringland
    nyoj221_Tree_subsequent_traversal
  • 原文地址:https://www.cnblogs.com/davidyang2415/p/2387372.html
Copyright © 2011-2022 走看看