C++源码—_Ptr_base(MSVC 2017)
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 */
};

浙公网安备 33010602011771号