boost智能指针

boost智能指针

1、RAII机制

RAII-- 资源获取即初始化,Resource Acquisition Is Initialization。是指使用资源的类在构造函数中申请资源,然后使用,在析构函数中释放资源。即以对象的方式管理指针。

★对象在栈上创建资源,由于作用域限制,过了作用域自动释放资源;

★对象在堆上创建资源,如new的方式,需要手动delete,可能造成内存泄漏。

2、boost的解决方式--智能指针

boost.smart_ptr库位于<boost/smart_ptr.hpp>提供六种智能指针:scoped_ptr/scoped_array/shared_ptr/shared_ptr/weak_ptr/initrusive_ptr.特点是轻量级对象、异常安全、要求指向的类型T的析构函数不能抛出异常。本文只介绍scoped_ptr、shared_ptr和weak_ptr。

3、scoped_ptr

3.1、特点

   包装了new操作符在堆上分配的动态对象,保证及时自动释放;原始指针的权限不能转让,即该智能指针只能在该作用域中使用,不希望被转让。

3.2、类实现

template<classT> class scoped_ptr // noncopyable

{

private:

    T * px; //原始指针

    scoped_ptr(scoped_ptr const &);//禁止拷贝构造

    scoped_ptr & operator=(scoped_ptr const&);//禁止赋值操作

    typedef scoped_ptr<T> this_type;

    void operator==( scoped_ptr const& )const;//禁止等于操作

    void operator!=( scoped_ptr const& )const;//禁止不等操作

public:

    typedef T element_type;

    explicitscoped_ptr( T * p = 0 ): px( p ) // never throws 显式构造

    {

#ifdefined(BOOST_SP_ENABLE_DEBUG_HOOKS)

        boost::sp_scalar_constructor_hook( px);

#endif

    }

    ~scoped_ptr()// never throws 析构

    {

        boost::checked_delete( px );

    }

    void reset(T * p = 0) // never throws 重置指针

    {

        BOOST_ASSERT( p == 0 || p != px ); //catch self-reset errors

        this_type(p).swap(*this);

    }

    T & operator*() const // never throws

    {

        BOOST_ASSERT( px != 0 );

        return *px;

    }

    T * operator->() const // never throws

    {

        BOOST_ASSERT( px != 0 );

        return px;

    }

    T * get() const BOOST_NOEXCEPT //获取原始指针

    {

        return px;

    }

    void swap(scoped_ptr & b)BOOST_NOEXCEPT //交换指针

    {

        T * tmp = b.px;

        b.px = px;

        px = tmp;

    }

};

3.3、说明

★ 接受的指针必须是new在堆上分配的

★ scoped_ptr接受一个new出来的指针,并在析构函数中自动释放

★reset函数更改保护的原始指针,尽量不用,以防原始指针失控

★ scoped_ptr不支持拷贝构造、赋值、等于、不等于操作,因此基于这些操作符的stl算法不能使用。

3.4、使用

只需要将使用原始指针的地方替换为scoped_ptr即可:

std::stringpStr = new std::string("hello");

scoped_ptr<string> sp(pStr);

std::stringsStr = *sp;

size_tnSize = sp->size();

注意scoped_ptr是不能进行赋值的。

4、shared_ptr

4.1、特点

包装new出来的原始指针;实现对原始指针的引用计数,只有在引用计数为0时才会被释放,因此可以支持拷贝和赋值;可以放在stl容器中。

4.2、类实现

template<classT> class shared_ptr

{

public:

    typedef typenameboost::detail::sp_element< T >::type element_type;

    shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn()// never throws in 1.30+

    {

    }

    template<class Y>

    explicit shared_ptr( Y * p): px( p ), pn() // Y must be complete

    {

        boost::detail::sp_pointer_construct(this, p, pn );

    }

    // Requirements: D's copy constructor mustnot throw 执行删除器D

    // shared_ptr will release p by callingd(p)

    template<class Y, class D>shared_ptr( Y * p, D d ): px( p ), pn( p, d )

    {

        boost::detail::sp_deleter_construct(this, p );

    }

    shared_ptr( shared_ptr const & r )BOOST_NOEXCEPT : px( r.px ), pn( r.pn )

    {

    }

    template<class Y>

    explicit shared_ptr( std::auto_ptr<Y>& r ): px(r.get()), pn()

    {

       boost::detail::sp_assert_convertible< Y, T >();

        Y * tmp = r.get();

        pn = boost::detail::shared_count( r );

        boost::detail::sp_deleter_construct(this, tmp );

    }

    template<class Y>

    shared_ptr & operator=(std::auto_ptr<Y> & r )

    {

        this_type( r ).swap( *this );

        return *this;

    }

    shared_ptr( shared_ptr && r )BOOST_NOEXCEPT : px( r.px ), pn()

    {

        pn.swap( r.pn );

        r.px = 0;

    }

    shared_ptr & operator=( shared_ptr&& r ) BOOST_NOEXCEPT

    {

        this_type( static_cast< shared_ptr&& >( r ) ).swap( *this );

        return *this;

    }

    template<class Y>

    shared_ptr & operator=(shared_ptr<Y> && r ) BOOST_NOEXCEPT

    {

        this_type( static_cast<shared_ptr<Y> && >( r ) ).swap( *this );

        return *this;

    }

    void reset() BOOST_NOEXCEPT // never throwsin 1.30+

    {

        this_type().swap(*this);

    }

    template<class Y> void reset( Y * p )// Y must be complete

    {

        BOOST_ASSERT( p == 0 || p != px ); //catch self-reset errors

        this_type( p ).swap( *this );

    }

    element_type * get() const BOOST_NOEXCEPT

    {

        return px;

    }

private:

    element_type * px;                 // contained pointer

   boost::detail::shared_count pn;   // reference counter

};  // shared_ptr

4.3、说明

shared_ptr支持拷贝和赋值,只不过引用计数+1;支持比较操作,相当于原始指针的比较。

4.4、用法

shared_ptr<int>sp(new int(10));

shared_ptr<int>sp2 = sp;

assert(sp== sp2 && sp.use_count() == 2 );

*sp2 =100;

assert(*sp== 100);

sp.reset();//停止sp的引用

assert(!sp);

5、weak_ptr

5.1特点

weak_ptr没有重载*和->,因此其并不能当作普通指针使用;其行为是对shared_ptr的一种协助,帮助监控当前引用计数,在需要的时候获取shared_ptr对象。

5.2、类实现

template<classT> class weak_ptr

{

public:

    typedef typenameboost::detail::sp_element< T >::type element_type;

    weak_ptr() BOOST_NOEXCEPT : px(0), pn() //never throws in 1.30+

    {

    }

    weak_ptr( weak_ptr const & r )BOOST_NOEXCEPT : px( r.px ), pn( r.pn )

    {

    }

    weak_ptr & operator=( weak_ptr const& r ) BOOST_NOEXCEPT

    {

        px = r.px;

        pn = r.pn;

        return *this;

    }

    template<class Y>

    weak_ptr & operator=(shared_ptr<Y> const & r ) BOOST_NOEXCEPT

    {

       boost::detail::sp_assert_convertible< Y, T >();

        px = r.px;

        pn = r.pn;

        return *this;

    }

    shared_ptr<T> lock() const BOOST_NOEXCEPT

    {

        return shared_ptr<T>( *this,boost::detail::sp_nothrow_tag() );

    }

    long use_count() const BOOST_NOEXCEPT

    {

        return pn.use_count();

    }

    bool expired()const BOOST_NOEXCEPT

    {

        return pn.use_count() == 0;

    }

    void reset() BOOST_NOEXCEPT // never throwsin 1.30+

    {

        this_type().swap(*this);

    }

    void swap(this_type & other)BOOST_NOEXCEPT

    {

        std::swap(px, other.px);

        pn.swap(other.pn);

    }

private:

    element_type * px;            // contained pointer

    boost::detail::weak_count pn; // referencecounter

};  // weak_ptr

5.3、说明

★lock函数从被观测的sharped_ptr获得一个可用sharped_ptr对象;

★expired函数判断weak_ptr观察的对象是否失效

★use_count函数获取被观察对象的指针引用计数

5.4、用法

shared_ptr<int>sp(new int(10));

assert(sp.use_count()== 1);

weak_ptr<int>wp(sp);

assert(wp.use_count()== 1);

if ( !wp.expired())

{

   shared_ptr<int> sp2 = wp.lock();

   *sp2 = 100;

   assert(wp.use_count() == 2);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值