boost智能指针代码简化版
刚开始因为不明白为什么use_count为0后weak_ptr还可以取得use_count, 所以看了一下shared_ptr和weak_ptr的代码, 这里把关键的代码都提取出来了,方便大家阅读
//sp_counted_base
class sp_counted_base
{
private:
// 不可复制
sp_counted_base( sp_counted_base const &);
sp_counted_base & operator= ( sp_counted_base const &);
// 两个成员, 只有弱计数到0了才会销毁对象
long use_count_; // 用于shared_ptr
long weak_count_; // 用于weak_ptr
public:
sp_counted_base() : use_count_( 1 ), weak_count_( 1 )
{
// 两个成员初始化为1
}
virtual ~sp_counted_base()
{
}
virtual void dispose() = 0; // 用于子类销毁自有的东西
virtual void destroy()
{
delete this;
}
void add_ref_copy()
{
BOOST_INTERLOCKED_INCREMENT( &use_count );
// 用于shared_ptr的复制赋值, 因为有shared_ptr就不怕对象被销毁
// 不用像下一个函数那么复杂
// BOOST_INTERLOCKED_INCREMENT 保证了原子操作
}
void add_ref_lock()
{
for ( ;; ) //最高效的死循环
{
long tmp = static_cast< long const volatile & >( use_count_ );
if ( tmp == 0 ) return false;
if ( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
// 这里 保证了在for的一次循环中, &use_count_的值没有被改变过的情况下把_usr_count递增1
// BOOST_INTERLOCKED_COMPARE_EXCHANGE的意思是
// use_count的值和 tmp相等时, use_count=tmp+1
// 返回的大概是use_count原来的值, 这个我还没查
}
}
void release()
{
if ( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
{
dispose(); // 指向的对象是删除了, 但sp_counted_base对象还要看下面情况
weak_release(); //use_count_为0了还要看weak_count_
}
}
void weak_add_ref()
{
BOOST_INTERLOCKED_INCREMENT( &weak_count_ ); // 用于weak_ptr
}
void weak_release()
{
if ( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const
{ // 确保最新最准的
return static_cast<long const volatile &>( use_count_ );
}
};
// sp_counted_base 一个子类
template<class X> class sp_counted_impl_p: public sp_counted_base
{
private:
X * px_; //存放指针处
// 不可复制
sp_counted_impl_p( sp_counted_impl_p const & );
sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
typedef sp_counted_impl_p<X> this_type;
public:
explicit sp_counted_impl_p( X * px ): px_( px )
{
//基类两个成员就默认设为1了
}
virtual void dispose()
{
boost::checked_delete( px_ );
}
};
// shared_count
// weak_count
class weak_count;
class shared_count
{
private:
sp_counted_base * pi_;
friend class weak_count;
public:
shared_count(): pi_(0)
{
}
template<class Y> explicit shared_count( Y * p)
{
try
{
pi_ = new sp_counted_impl_p<Y>( p );
}
catch(...)
{
boost::checked_delete( p ); //当Y不是完整类型时编译会出错,具体请百度
throw
}
}
~shared_count()
{
if ( pi_ != 0 ) pi_->release();
}
shared_count(shared_count const & r): pi_(r.pi_)
{
if( pi_ != 0 ) pi_->add_ref_copy();
}
shared_count(shared_count && r): pi_(r.pi) //C++新特性, 还没查资料, 先站位
{
r.pi_ = 0;
}
//因为weak_count还没定义
//所以这个函数后面才定义
shared_count(weak_count const & r, sp_nothrow_tag);
shared_count & operator= (shared_count const & r)
{
sp_counted_base * tmp = r.pi_;
if (tmp != pi_ )
{
if (tmp != 0 ) tmp->add_ref_copy();
if (pi_ != 0 ) pi_->release();
return this;
}
}
void swap(shared_count & r)
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const
{
return pi_ != 0 ? pi_->use_count() : 0;
}
bool unique() const
{
return use_count() == 1;
}
bool empty() const
{
return pi_ == 0;
}
};
class weak_count
{
private:
sp_counted_base * pi_;
friend class shared_count;
public:
weak_count(): pi_(0)
{
}
weak_count()(shared_count const & r ): pi_(r.pi_)
{
if(pi_ != 0) pi_->weak_add_ref();
}
weak_count()(weak_count const & r ): pi_(r.pi_)
{
if(pi_ != 0) pi_->weak_add_ref();
}
~weak_count()
{
if(pi_ != 0) pi_->weak_release();
//开始时只增加了weak_count_所以析构时只减少weak_count_
}
weak_count & operator= (shared_count const & r)
{
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;
}
void swap(weak_count & r)
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const
{
return pi_ != 0? pi_->use_count(): 0;
}
bool empty() const
{
return pi_ == 0;
}
};
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag): pi_( r.pi_ )
{
if( pi_ != 0 && !pi_->add_ref_lock() )
{
pi_ = 0;
}
}
template<class T> class weak_ptr
{
// 不用析构函数的, 默认的析构函数够用了
private:
typedef weak_ptr<T> this_type;
T *px;
weak_count pn; //不是指针
public:
weak_ptr(): px(0), pn()
{
}
template<class Y>
weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
: px(r.lock().get()), pn(r.pn)
{
//如果用:px(r.px),pn(r.pn)在多线程下不安全
//sp_enable_if_convertible的代码请找源码
}
template<class Y>
weak_ptr( shared_ptr<Y> const r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
:px(r.px), pn(r.pn)
{
}
template<class Y>
weak_ptr & operator=(weak_ptr<Y> const & r)
{
px = r.lock().get(); //这里编译期保证了是否能够转换
pn = r.pn;
}
template<class Y>
weak_ptr & operator=(shared_ptr<Y> const & r)
{
px = r.px;
pn = r.pn;
return *this;
}
shared_ptr<T> lock() const
{
return shared_ptr<this_type>( *this, boost::detail::sp_nothrow_tag() );
}
long use_count() const
{
return pn.use_count();
}
bool expired() const
{
return pn.use_count() == 0;
}
void reset()
{
this_type().swap(*this);
}
void swap(this_type & other)
{
std::swap(px, other.px);
pn.swap(other.pn);
}
};
template<class T> class shared_ptr
{
// 不用析构函数的, 默认的析构函数够用了
private:
typedef shared_ptr<T> this_type;
T * px;
shared_count pn;
public:
shared_ptr(): px(0), pn()
{
}
template<class Y>
explicit shared_ptr( Y* p): px( p ), pn( p )
{
//还没弄懂这句
boost::detail::sp_enable_shared_from_this( this, p, p );
}
template<class Y>
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
{
if( !pn.empty() )
{
px = r.px;
}
}
template<class Y>
shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
: px( r.px ), pn( r.pn )
{
}
shared_ptr & operator=( shared_ptr const & r )
{
this_type(r).swap(*this);
return *this;
}
template<class Y>
shared_ptr & operator=(shared_ptr<Y> const & r)
{
this_type(r).swap(*this);// this_type(r)保证了Y和T能够转换
return *this;
}
void reset()
{
this_type().swap(*this);
}
template<class Y> void reset(Y * p)
{
BOOST_ASSERT(p == 0 || p != px); //保证不用自己的指针重设
this_type(p).swap(*this);
}
// 如果T是 void const, void volatile, void const volatile会有不同,
// 具体请看源码
T & opterator* () const
{
BOOST_ASSERT(px != 0);
return *px;
}
T * opterator-> () const
{
BOOST_ASSERT(px != 0); //vc上等于assert(px != 0), 其它编译器没看
return px;
}
T * get() const
{
return px;
}
////////////////////////////这里插入了一段unspecified_bool_type的东西
//用于隐式转换成bool
#include <boost/smart_ptr/detail/operator_bool.hpp>
////////////////////////////
bool unique() const
{ //书中说use_count效率比unique低, 但从代码中看不是这样
return pn.unique();
}
long use_count() const
{
return pn.use_count();
}
void swap(shared_ptr<T> & other)
{
std::swap(px, other.px);
pn.swap(other.pn);
}
};

浙公网安备 33010602011771号