c++11 智能指针

share_ptr

首先来看shared_ptr,先贴一小部分vs2013里的实现

// TEMPLATE CLASS shared_ptr
template<class _Ty>
class shared_ptr
  : public _Ptr_base<_Ty>
{   // class for reference counted resource management
public:
typedef shared_ptr<_Ty> _Myt;
typedef _Ptr_base<_Ty> _Mybase;

shared_ptr() _NOEXCEPT
  { // construct empty shared_ptr
  }

template<class _Ux>
  explicit shared_ptr(_Ux *_Px)
  { // construct shared_ptr object that owns _Px
  _Resetp(_Px);
  }

template<class _Ux,
  class _Dx>
  shared_ptr(_Ux *_Px, _Dx _Dt)
  { // construct with _Px, deleter
  _Resetp(_Px, _Dt);
  }

shared_ptr(nullptr_t)
  { // construct empty shared_ptr
  }
  ......
}

我们可以看到shared_ptr首先继承了_Ptr_base。把_Ptr_base部分代码贴上来

// TEMPLATE CLASS _Ptr_base
template<class _Ty>
class _Ptr_base
{   // base class for shared_ptr and weak_ptr
public:
typedef _Ptr_base<_Ty> _Myt;
typedef _Ty element_type;

_Ptr_base()
  : _Ptr(0), _Rep(0)
  { // construct
  }

_Ptr_base(_Myt&& _Right)
  : _Ptr(0), _Rep(0)
  { // construct _Ptr_base object that takes resource from _Right
  _Assign_rv(_STD forward<_Myt>(_Right));
  }

template<class _Ty2>
  _Ptr_base(_Ptr_base<_Ty2>&& _Right)
  : _Ptr(_Right._Ptr), _Rep(_Right._Rep)
  { // construct _Ptr_base object that takes resource from _Right
  _Right._Ptr = 0;
  _Right._Rep = 0;
  }

_Myt& operator=(_Myt&& _Right)
  { // construct _Ptr_base object that takes resource from _Right
  _Assign_rv(_STD forward<_Myt>(_Right));
  return (*this);
  }
private:
  _Ty *_Ptr;
    _Ref_count_base *_Rep;
    template<class _Ty0>
        friend class _Ptr_base;
}

可以发现_Ptr就是用来保存原始指针的变量,_Rep是_Ref_count_base类型的指针,根据变量名大概就是引用计数了。再把_Ref_count_base的代码贴上来

// CLASS _Ref_count_base
class _Ref_count_base
{   // common code for reference counting
private:
virtual void _Destroy() = 0;
virtual void _Delete_this() = 0;

private:
_Atomic_counter_t _Uses;
_Atomic_counter_t _Weaks;

protected:
_Ref_count_base()
  { // construct
  _Init_atomic_counter(_Uses, 1);
  _Init_atomic_counter(_Weaks, 1);
  }

public:
virtual ~_Ref_count_base() _NOEXCEPT
  { // ensure that derived classes can be destroyed properly
  }

bool _Incref_nz()
  { // increment use count if not zero, return true if successful
  for (; ; )
    {   // loop until state is known
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_CEE_PURE)
    _Atomic_integral_t _Count =
      static_cast<volatile _Atomic_counter_t&>(_Uses);

    if (_Count == 0)
      return (false);

    if (static_cast<_Atomic_integral_t>(_InterlockedCompareExchange(
        reinterpret_cast<volatile long *>(&_Uses),
        _Count + 1, _Count)) == _Count)
      return (true);

#else /* defined(_M_IX86) || defined(_M_X64) || defined(_M_CEE_PURE) */
    _Atomic_integral_t _Count =
      _Load_atomic_counter(_Uses);

    if (_Count == 0)
      return (false);

    if (_Compare_increment_atomic_counter(_Uses, _Count))
      return (true);
#endif /* defined(_M_IX86) || defined(_M_X64) || defined(_M_CEE_PURE) */
    }
  }

unsigned int _Get_uses() const
  { // return use count
  return (_Get_atomic_count(_Uses));
  }

void _Incref()
  { // increment use count
  _MT_INCR(_Mtx, _Uses);
  }

void _Incwref()
  { // increment weak reference count
  _MT_INCR(_Mtx, _Weaks);
  }

void _Decref()
  { // decrement use count
  if (_MT_DECR(_Mtx, _Uses) == 0)
    {   // destroy managed resource, decrement weak reference count
    _Destroy();
    _Decwref();
    }
  }

void _Decwref()
  { // decrement weak reference count
  if (_MT_DECR(_Mtx, _Weaks) == 0)
    _Delete_this();
  }

long _Use_count() const
  { // return use count
  return (_Get_uses());
  }

bool _Expired() const
  { // return true if _Uses == 0
  return (_Get_uses() == 0);
  }

virtual void *_Get_deleter(const _XSTD2 type_info&) const
  { // return address of deleter object
  return (0);
  }
};

比较短就全贴上来了,可以看到_Uses和_Weaks都被初始化成1。当我们平时使用 std::shared_ptr a(new int(1)) 这种形式,shared_ptr会使用_Resetp()来初始化。把_Resetp()代码贴上来

template<class _Ux>
        void _Resetp(_Ux *_Px)
        {   // release, take ownership of _Px
        _TRY_BEGIN  // allocate control block and reset
        _Resetp0(_Px, new _Ref_count<_Ux>(_Px));
        _CATCH_ALL  // allocation failed, delete resource
        delete _Px;
        _RERAISE;
        _CATCH_END
        }
...
public:
    template<class _Ux>
        void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx)
        {   // release resource and take ownership of _Px
        this->_Reset0(_Px, _Rx);
        _Enable_shared(_Px, _Rx);
        }
....  
    // TEMPLATE CLASS _Ref_count
template<class _Ty>
class _Ref_count
: public _Ref_count_base
{   // handle reference counting for object without deleter
public:
_Ref_count(_Ty *_Px)
  : _Ref_count_base(), _Ptr(_Px)
  { // construct
  }

private:
virtual void _Destroy()
  { // destroy managed resource
  delete _Ptr;
  }

virtual void _Delete_this()
  { // destroy self
  delete this;
  }

_Ty * _Ptr;
};
....
void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
  { // release resource and take new resource
  if (_Rep != 0)
    _Rep->_Decref();
  _Rep = _Other_rep;
  _Ptr = _Other_ptr;
  }

可以看到最终在_Reset0中原始指针和在堆中的引用计数的指针都被保存下来,一个有趣的发现在引用计数中还保存着一份原始指针,有时间再慢慢探索。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值