shared_ptr智能指针源码分析
1 先写应用代码
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> sptr(new int(42));
// sptr1 = std::make_shared<int>(32);
std::shared_ptr<int> sp2 = sptr;
std::weak_ptr<int >wptr;
wptr = sptr;
std::cout << "Hello World!\n";
}
2 查看源码
shared_ptr和weak_ptr都继承于基类_Ptr_base,基类里有原始指针_Ptr和计数类指针*Rep。*
_Ref_count_base计数类是虚基类。有2个纯虚函数和强弱指针的 计数:
virtual void _Destroy() noexcept = 0;
virtual void _Delete_this() noexcept = 0;
_Atomic_counter_t _Uses;//强指针次数
_Atomic_counter_t _Weaks;//弱指针次数
_Ref_count实现其虚函数。
_Ref_count有其独有的指针: _Ty * _Ptr;//内部指针
3 单步调试
进入 memory文件里std::shared_ptr定义
查看引用shared_ptr的代码,找到shared_ptr构造函数:
template<class _Ux,
enable_if_t<conjunction_v<conditional_t<is_array_v<_Ty>, _Can_array_delete<_Ux>, _Can_scalar_delete<_Ux>>,
_SP_convertible<_Ux, _Ty>>, int> = 0>
explicit shared_ptr(_Ux * _Px)
{ // construct shared_ptr object that owns _Px
_Setp(_Px, is_array<_Ty>{});
}
设置断点调试f11进入
要构造函数需要先进入基类的构造函数,
程序进入到std::_Ptr_base<_Ty0>
初始化类成员
原始指针 element_type * _Ptr{nullptr};
private:
element_type * _Ptr{nullptr};//原始指针
_Ref_count_base * _Rep{nullptr};
首先 构造 计数器 类 new _Ref_count<_Ux>(_Px)
计数器 类_Ref_count可以看出继承于虚基类_Ref_count_base
template<class _Ty>
class _Ref_count
: public _Ref_count_base
{ // handle reference counting for pointer without deleter
public:
explicit _Ref_count(_Ty * _Px)
: _Ref_count_base(), _Ptr(_Px)
{ // construct
}
private:
virtual void _Destroy() noexcept override
{ // destroy managed resource
delete _Ptr;
}
virtual void _Delete_this() noexcept override
{ // destroy self
delete this;
}
_Ty * _Ptr;
};
进入虚基类_Ref_count_base
_Ref_count_base()
: _Uses(1), _Weaks(1) // non-atomic initializations
{ // construct
}
_Atomic_counter_t _Uses;//强指针次数
_Atomic_counter_t _Weaks;//弱指针次数
初始化 _Uses(1), _Weaks(1) 指针次数为1
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;
_Atomic_counter_t _Weaks;
protected:
_Ref_count_base()
: _Uses(1), _Weaks(1) // non-atomic initializations
{ // construct
}
public:
略
};
再F11 进入 shared_ptr 构造函数里调用的 成员函数_Setp
template<class _Ux>
void _Setp(_Ux * _Px, false_type)
{ // take ownership of _Px
_TRY_BEGIN // allocate control block and set
_Set_ptr_rep_and_enable_shared(_Px, new _Ref_count<_Ux>(_Px));
_CATCH_ALL // allocation failed, delete resource
delete _Px;
_RERAISE;
_CATCH_END
}
继续F11 执行 _Set_ptr_rep_and_enable_shared(_Px, new _Ref_count<_Ux>(_Px));
进入 shared_ptr 成员函数 _Set_ptr_rep_and_enable_shared
template<class _Ux>
void _Set_ptr_rep_and_enable_shared(_Ux * _Px, _Ref_count_base * _Rx)
{ // take ownership of _Px
this->_Set_ptr_rep(_Px, _Rx);
_Enable_shared_from_this(*this, _Px);
}
进入this->_Set_ptr_rep(_Px, _Rx);
shared_ptr 未重写 _Set_ptr_rep,因此进入基类_Ptr_base的成员函数_Set_ptr_rep
void _Set_ptr_rep(element_type * _Other_ptr, _Ref_count_base * _Other_rep)
{ // take new resource
_Ptr = _Other_ptr;
_Rep = _Other_rep;
}
进入_Enable_shared_from_this
template<class _Other,
class _Yty>
void _Enable_shared_from_this(const shared_ptr<_Other>& _This, _Yty * _Ptr)
{ // possibly enable shared_from_this
_Enable_shared_from_this1(_This, _Ptr, bool_constant<conjunction_v<
negation<is_array<_Other>>,
negation<is_volatile<_Yty>>,
_Can_enable_shared<_Yty>>>{});
}
继续运行 std::shared_ptr sp2 = sptr;//拷贝构造
当有其他强指针指向时,强指针计数增加
调用shared_ptr的拷贝构造,构建拥有与_Other相同资源的shared_ptr对象。这里是构建sp2,使其拥有和sptr一样的资源。
shared_ptr(const shared_ptr& _Other) noexcept
{ // construct shared_ptr object that owns same resource as _Other
this->_Copy_construct_from(_Other);
}
拷贝构造的实现:实现shared_ptr的(转换)复制ctor
其实就是 _Ptr_base的成员变量 原始指针和计数的复制 并无再分配空间 (unique指针是禁止了拷贝构造 )
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;
}
运行最后减少计数 析构摧毁资源 销毁被管理的资源,减去弱引用计数
_Ref_count_base::_Decref()
void _Decref()
{ // decrement use count
if (_MT_DECR(_Uses) == 0)
{ // destroy managed resource, decrement weak reference count
_Destroy();
_Decwref();
}
}
_Ref_count ::_Destroy() 删除原始指针占用的资源
private:
virtual void _Destroy() noexcept override
{ // destroy managed resource
delete _Ptr;
}