boost shared_ptr实现浅析

版本boost 1.43.0
头文件<boost/shared_ptr.hpp>


shared_ptr是boost中最强大的智能指针,基于C++非常精巧的实现了“引用计数”的功能

shared_ptr只有两个类成员变量

T * px;                     // contained pointer
boost::detail::shared_count pn;    // reference counter

px是指向实际对象的指针,而pn就是用来计数的类了。



原来一直很好奇shared_ptr是如何在不同对象中共享引用计数的,其实很简单,shared_count类可以看成是一个指向计数器的指针,
不同的shared_ptr类都指向同一个计数器地址,这样就达到共享的目的了。


再从代码级别来详细了解一下

shared_count只有一个成员变量

sp_counted_base * pi_;

pi_实际是一个指向sp_counted_base的子类sp_counted_impl_p*(*由编译选项确定),

一般来说,sp_counted_base中实现了add_ref_copy和release这些对引用计数操作的接口,而sp_counted_impl_p*则实现了allocator和deallocator这些接口
值得注意的是add_ref_copy和release都是“原子”操作,所以针对不同平台有不同的sp_counted_base实现,这个类似kernel里的atomic_t


再来看下shared_ptr的赋值操作
shared_ptr & operator=( shared_ptr && r ) // never throws
{
     this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
     return *this;
}

this_type( static_cast< shared_ptr && >( r ) )生成一个临时对象,然后和this交换,注意就是这个临时对象给引用计数加1了。
swap函数的实现如下
void swap(shared_ptr<T> & other) // never throws
{
	std::swap(px, other.px);
	pn.swap(other.pn);
}
px的swap很简单,pn的swap调用了shared_count自定义的swap函数,实现如下
void swap(shared_count & r) // nothrow
{
	sp_counted_base * tmp = r.pi_;
	r.pi_ = pi_;
	pi_ = tmp;
}

这里只是交换了“引用计数”的指针。


临时对象在构造的时候是如何增加引用计数的呢?考虑如下场景
shared_ptr<T> ptr1(new T);
shared_ptr<T> ptr2(ptr1);

再来看看shared_ptr的代码是如何实现的
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
	boost::detail::sp_enable_shared_from_this( this, p, p );
}

可以看到这里px和pn调用的都是赋值操作,px自不必说,pn的赋值函数如下
shared_count & operator= (shared_count const & r) // nothrow
{
	sp_counted_base * tmp = r.pi_;


	if( tmp != pi_ )
	{
		if( tmp != 0 ) tmp->add_ref_copy();
		if( pi_ != 0 ) pi_->release();
		pi_ = tmp;
	}


	return *this;
}

这里很明显原来的计数被release,而新的计数被add_ref_copy了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值