1 _Ptr_base
_Ptr_base 是智能指针的基类,它包含两个成员变量:指向目标元素的指针 _Ptr 和 引用计数基类指针 _Rep。
private: element_type * _Ptr{nullptr}; _Ref_count_base * _Rep{nullptr};
1.1 element_type * _Ptr
_Ptr 指向的元素类型为 using element_type = remove_extent_t<_Ty>,remove_extent_t 会移除类型中的数组,如果类型是多维数组,则只移除第一维。
int a, b[3]; typeid(remove_extent<int>::type) == typeid(a); //true typeid(remove_extent<int[]>::type) == typeid(a); //true typeid(remove_extent<int[][3]>::type) == typeid(a); //flase typeid(remove_extent<int[][3]>::type) == typeid(b); //true
1.2 _Ref_count_base * _Rep
_Ref_count_base 是引用计数基类,它包含两个成员变量:原子计数器 _Uses 和 弱引用计数 _Weaks。
_MT_INCR 和 _MT_DECR 是宏定义,实现原子操作。
#define _MT_INCR(x) _InterlockedIncrement(reinterpret_cast<volatile long *>(&x))
#define _MT_DECR(x) _InterlockedDecrement(reinterpret_cast<volatile long *>(&x))
当 _Uses 为 0 时,调用 _Destroy() 释放对象;当 _Weaks 为 0 时,调用 _Delete_this() 释放 _Ref_count_base。此外就是一些引用计数的增加、减少等函数的实现。
class __declspec(novtable) _Ref_count_base { // common code for reference counting private: #ifdef _M_CEE_PURE virtual void _Destroy() noexcept { // permanent workaround to avoid mentioning _purecall in msvcurt.lib, ptrustu.lib, or other support libs _STD terminate(); } virtual void _Delete_this() noexcept { // permanent workaround to avoid mentioning _purecall in msvcurt.lib, ptrustu.lib, or other support libs _STD terminate(); } #else /* ^^^ _M_CEE_PURE ^^^ // vvv !_M_CEE_PURE vvv */ virtual void _Destroy() noexcept = 0; virtual void _Delete_this() noexcept = 0; #endif /* _M_CEE_PURE */ _Atomic_counter_t _Uses; //原子计数器, unsigned long _Atomic_counter_t _Weaks; //弱引用计数 protected: _Ref_count_base() : _Uses(1), _Weaks(1) // non-atomic initializations { // construct } public: virtual ~_Ref_count_base() noexcept { // TRANSITION, should be non-virtual } bool _Incref_nz() { // increment use count if not zero, return true if successful for (;;) { // loop until state is known #if _USE_INTERLOCKED_REFCOUNTING const _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), static_cast<long>(_Count + 1), static_cast<long>(_Count))) == _Count) return (true); #else /* _USE_INTERLOCKED_REFCOUNTING */ const _Atomic_integral_t _Count = _Load_atomic_counter(_Uses); if (_Count == 0) return (false); if (_Compare_increment_atomic_counter(_Uses, _Count)) return (true); #endif /* _USE_INTERLOCKED_REFCOUNTING */ } } void _Incref() { // increment use count _MT_INCR(_Uses); } void _Incwref() { // increment weak reference count _MT_INCR(_Weaks); } void _Decref() { // decrement use count if (_MT_DECR(_Uses) == 0) { // destroy managed resource, decrement weak reference count _Destroy(); _Decwref(); } } void _Decwref() { // decrement weak reference count if (_MT_DECR(_Weaks) == 0) { _Delete_this(); } } long _Use_count() const noexcept { // return use count return (static_cast<long>(_Get_atomic_count(_Uses))); } virtual void * _Get_deleter(const type_info&) const noexcept { // return address of deleter object return (nullptr); } };
1.3 成员函数
template<class _Ty> class _Ptr_base { // base class for shared_ptr and weak_ptr public: using element_type = remove_extent_t<_Ty>; _NODISCARD long use_count() const noexcept { // return use count return (_Rep ? _Rep->_Use_count() : 0); } template<class _Ty2> _NODISCARD bool owner_before(const _Ptr_base<_Ty2>& _Right) const noexcept { // compare addresses of manager objects return (_Rep < _Right._Rep); } _Ptr_base(const _Ptr_base&) = delete; _Ptr_base& operator=(const _Ptr_base&) = delete; protected: _NODISCARD element_type * get() const noexcept { // return pointer to resource return (_Ptr); } constexpr _Ptr_base() noexcept = default; ~_Ptr_base() = default; template<class _Ty2> void _Move_construct_from(_Ptr_base<_Ty2>&& _Right) { // implement shared_ptr's (converting) move ctor and weak_ptr's move ctor _Ptr = _Right._Ptr; _Rep = _Right._Rep; _Right._Ptr = nullptr; _Right._Rep = nullptr; } template<class _Ty2> void _Copy_construct_from(const shared_ptr<_Ty2>& _Other) { // implement shared_ptr's (converting) copy ctor if (_Other._Rep) { _Other._Rep->_Incref(); } _Ptr = _Other._Ptr; _Rep = _Other._Rep; } template<class _Ty2> void _Alias_construct_from(const shared_ptr<_Ty2>& _Other, element_type * _Px) { // implement shared_ptr's aliasing ctor if (_Other._Rep) { _Other._Rep->_Incref(); } _Ptr = _Px; _Rep = _Other._Rep; } template<class _Ty0> friend class weak_ptr; // specifically, weak_ptr::lock() template<class _Ty2> bool _Construct_from_weak(const weak_ptr<_Ty2>& _Other) { // implement shared_ptr's ctor from weak_ptr, and weak_ptr::lock() if (_Other._Rep && _Other._Rep->_Incref_nz()) { _Ptr = _Other._Ptr; _Rep = _Other._Rep; return (true); } return (false); } void _Decref() { // decrement reference count if (_Rep) { _Rep->_Decref(); } } void _Swap(_Ptr_base& _Right) noexcept { // swap pointers _STD swap(_Ptr, _Right._Ptr); _STD swap(_Rep, _Right._Rep); } void _Set_ptr_rep(element_type * _Other_ptr, _Ref_count_base * _Other_rep) { // take new resource _Ptr = _Other_ptr; _Rep = _Other_rep; } template<class _Ty2> void _Weakly_construct_from(const _Ptr_base<_Ty2>& _Other) { // implement weak_ptr's ctors if (_Other._Rep) { _Other._Rep->_Incwref(); } _Ptr = _Other._Ptr; _Rep = _Other._Rep; } void _Decwref() { // decrement weak reference count if (_Rep) { _Rep->_Decwref(); } } private: element_type * _Ptr{nullptr}; //指向目标元素 _Ref_count_base * _Rep{nullptr}; //引用计数基类指针 template<class _Ty0> friend class _Ptr_base; #if _HAS_STATIC_RTTI template<class _Dx, class _Ty0> friend _Dx * get_deleter(const shared_ptr<_Ty0>& _Sx) noexcept; #endif /* _HAS_STATIC_RTTI */ };