boost之智能指针

简介

boost中的智能指针有

  • shared_ptr
  • weak_ptr
  • scoped_ptr
  • intrusive_ptr

shared_ptr

结构为

shared_ptr<T>
- element_type * px
- shared_count pn
shared_count
- sp_counted_base * pi_
+shared_count(Y * p)
sp_counted_base
- int use_count_
- int weak_count_
+void dispose()
+void * get_deleter(sp_typeinfo const & ti)
+void * get_untyped_deleter()
sp_counted_impl_p<T>
- X * px_

sp_counted_base的dispose,get_deleter和get_untyped_deleter为纯虚函数,其默认构造函数将use_count_和weak_count_初始化为1

sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    {
    }

shared_count(shared_count const & r)构造函数会创建sp_counted_base 的子类,其拷贝构造函数会将引用计数+1

shared_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
    , id_(shared_count_id)
#endif
{
    if( pi_ != 0 ) pi_->add_ref_copy();
}
    
class sp_counted_base
{
	 void add_ref_copy()
    {
        atomic_increment( &use_count_ );
    }
}

shared_count(weak_count const & r)构造函数作sp_counted_base的赋值,同时会增加引用计数。如果指针为空或者引用计数为0会抛出异常

inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
        , id_(shared_count_id)
#endif
{
    if( pi_ == 0 || !pi_->add_ref_lock() )
    {
        boost::throw_exception( boost::bad_weak_ptr() );
    }
}

sp_counted_impl_p,内部存储对象的指针
shared_ptr( Y * p )会调用sp_pointer_construct,对于实现了enable_shared_from_this的类,会调用_internal_accept_owner

//shared_ptr类
template<class Y>
 explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
 {
     boost::detail::sp_pointer_construct( this, p, pn );
 }

//sp_pointer_construct函数模板
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
{
    boost::detail::shared_count( p ).swap( pn );
    boost::detail::sp_enable_shared_from_this( ppx, p, p );
}
//sp_enable_shared_from_this函数模板
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
{
    if( pe != 0 )
    {
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
    }
}
//enable_shared_from_this类模板
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
    {
        if( weak_this_.expired() )
        {
            weak_this_ = shared_ptr<T>( *ppx, py );
        }
    }

enable_shared_from_this:类在调用_internal_accept_owner时,会使用下面的shared_tp复制构造函数

template< class Y >
    shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
    {
    }

shared_ptr( weak_ptr<Y> const & r )将指针赋值给shared_ptr,同时将weak_count赋值给shared_count

template<class Y>
    explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
    {
        boost::detail::sp_assert_convertible< Y, T >();

        // it is now safe to copy r.px, as pn(r.pn) did not throw
        px = r.px;
    }

weak_ptr

结构为

weak_ptr<T>
- element_type * px
- weak_count pn
weak_count
- sp_counted_base * pi_
sp_counted_base

构造函数weak_count(shared_count const & r)会增加sp_counted_base 的弱引用计数

weak_count(shared_count const & r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
        , id_(weak_count_id)
#endif
    {
        if(pi_ != 0) pi_->weak_add_ref();
    }
    
 void weak_add_ref() // nothrow
 {
     atomic_increment( &weak_count_ );
 }

赋值构造函数weak_count & operator= (shared_count const & r),会将当前的sp_counted_base销毁,同时增加来源的弱引用计数

weak_count & operator= (shared_count const & r) // nothrow
    {
        sp_counted_base * tmp = r.pi_;

        if( tmp != pi_ )
        {
            if(tmp != 0) tmp->weak_add_ref();
            if(pi_ != 0) pi_->weak_release();
            pi_ = tmp;
        }

        return *this;
    }

intrusive_ptr

需要对象自己实现友元函数

void intrusive_ptr_add_ref(T * p);
void intrusive_ptr_release(T * p);

类结构为

intrusive_ptr<T>
- T* px
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值