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::type) == typeid(a); //true typeid(remove_extent ::type) == typeid(a); //true typeid(remove_extent ::type) == typeid(a); //flase typeid(remove_extent ::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
#define _MT_DECR(x) _InterlockedDecrement(reinterpret_cast
当 _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(_Uses);
if (_Count == 0)
return (false);
if (static_cast<_Atomic_integral_t>(_InterlockedCompareExchange(
reinterpret_cast(&_Uses),
static_cast(_Count + 1), static_cast(_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(_Get_atomic_count(_Uses)));
}
virtual void * _Get_deleter(const type_info&) const noexcept
{ // return address of deleter object
return (nullptr);
}
};
1.3 成员函数
templateclass _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 _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 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 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 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 friend class weak_ptr; // specifically, weak_ptr::lock() template 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 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 friend class _Ptr_base; #if _HAS_STATIC_RTTI template friend _Dx * get_deleter(const shared_ptr<_Ty0>& _Sx) noexcept; #endif /* _HAS_STATIC_RTTI */ };