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);
  }
};

  

原文链接: https://www.cnblogs.com/one-piece/archive/2011/09/28/2194890.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    boost智能指针代码简化版

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/33257

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午10:24
下一篇 2023年2月8日 上午10:26

相关推荐