赞
踩
#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";
}
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;//内部指针
进入 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;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。