C++11里shared_ptr源码剖析
来源:互联网 发布:图像算法工程师容易吗? 编辑:程序博客网 时间:2024/06/03 19:07
很多人不知道引用计数放在哪,昨天为止我也不知道,O(∩_∩)O哈哈~
A *a = new A;shared_ptr<A> sp(a);
上面代码发生了什么呢?
进入shared_ptr的构造函数
template<class _Ux> explicit shared_ptr(_Ux *_Px){ _Resetp0(_Px, new _Ref_count<_Ux>(_Px));//这里是new出来的_Ref_count }
1.shared_ptr继承_Ptr_base
2.Ptr_base里面有两个东西
private: _Ty *_Ptr; _Ref_count_base *_Rep;
一个是指向传进来的地址,一个是_Ref_count_base(用于保存引用计数,并且和week_ptr交流的一个类)基类是_Ref_count_base,引用计数就在基类里面
private: _Atomic_counter_t _Uses; _Atomic_counter_t _Weaks;
3.然后调用_Resetp0
template<class _Ux>void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx){ this->_Reset0(_Px, _Rx); _Enable_shared(_Px, _Rx);}
4.然后调用_Reset0
void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep){ //释放资源 and 利用新资源 if (_Rep != 0) _Rep->_Decref();//如果原来有资源,释放原来的资源 _Rep = _Other_rep; _Ptr = _Other_ptr;}
5.把上面new的_Ref_count<_Ux>(_Px)赋值给_Ptr_base里面的_Ptr
把传进来的指针赋值给_Ptr
6.这样share_ptr里面就有一个_Ref_count了,这个_Ref_count在初始化的时候会把两个引用计数都赋值为1
_Ref_count_base(){ _Init_atomic_counter(_Uses, 1); _Init_atomic_counter(_Weaks, 1);}
为啥weeks是1呢?不应该是0么?
因为在析构的时候weeks计数器是先减一再判断为不为0
// decrement weak reference countif (_MT_DECR(_Mtx, _Weaks) == 0) delete this;
很重要★★★★因为shared和weak都是共用一个_Ref_count_base
当所有的week_ptr都没了才释放自己,不然之后week访问这个类就会出错
有点晕?看幅图
下面是我精简后的源码,可以更好加深理解
template<class _Ty>class _Ptr_base{public: _Ptr_base(): _Ptr(0), _Rep(0){} long use_count() { // _Ref_count_base 存在就返回用户的引用个数 为NULL就返回0 return (_Rep ? _Rep->_Use_count() : 0); } void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep) { //释放资源 and 利用新资源 if (_Rep != 0) _Rep->_Decref();//如果原来有资源,释放原来的资源 _Rep = _Other_rep; _Ptr = _Other_ptr; } ///////////////////赋值///////////////////////// shared_ptr(const _Myt& _Other) _NOEXCEPT { _Reset(_Other._Ptr, _Other._Rep); } void _Reset(_Ty *_Other_ptr, _Ref_count_base *_Other_rep) { // release resource and take _Other_ptr through _Other_rep if (_Other_rep) _Other_rep->_Incref();//这里会把_Ref_count_base里面的_Uses + 1 _Reset0(_Other_ptr, _Other_rep); } //资源释放 void _Decref(){ if (_Rep != 0) _Rep->_Decref(); }private: _Ty *_Ptr; _Ref_count_base *_Rep; };
template<class _Ty>class shared_ptr: public _Ptr_base<_Ty>{public: template<class _Ux> explicit shared_ptr(_Ux *_Px){ _Resetp0(_Px, new _Ref_count<_Ux>(_Px));//这里是new出来的_Ref_count }private: template<class _Ux> void _Resetp(_Ux *_Px) { // release, take ownership of _Px _Resetp0(_Px, new _Ref_count<_Ux>(_Px)); } template<class _Ux> void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx) { this->_Reset0(_Px, _Rx); _Enable_shared(_Px, _Rx); } ~shared_ptr() _NOEXCEPT { // release resource this->_Decref(); }};
class _Ref_count_base{protected: _Ref_count_base() { // construct _Init_atomic_counter(_Uses, 1); _Init_atomic_counter(_Weaks, 1); } void _Decref() { // uses - 1 等于0 就是放资源 if (_MT_DECR(_Mtx, _Uses) == 0) { // destroy managed resource, decrement weak reference count delete _Ptr;//直接delete // decrement weak reference count if (_MT_DECR(_Mtx, _Weaks) == 0)//很重要★★★★因为shared和weak都是共用一个_Ref_count_base delete this;//当所有的week_ptr都没了才释放自己,不然week访问这个类就会出错 } }private: _Atomic_counter_t _Uses; _Atomic_counter_t _Weaks; };
template<class _Ty>class _Ref_count: public _Ref_count_base{ // handle reference counting for object without deleterpublic: _Ref_count(_Ty *_Px): _Ref_count_base(), _Ptr(_Px){}private: virtual void _Destroy() { delete _Ptr; } virtual void _Delete_this() { // destroy self delete this; } _Ty * _Ptr;};
阅读全文
0 0
- C++11里shared_ptr源码剖析
- C++ shared_ptr源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- shared_ptr智能指针源码剖析
- boost源码剖析3----内存管理shared_ptr
- 智能指针之shared_ptr框架源码剖析
- c/c++:strlen源码剖析
- Lua源码剖析(lmathlib.c)
- Lua源码剖析(lstrlib.c)
- C++STL源码剖析代码
- 深入剖析智能指针 shared_ptr
- nodejs基础教程--require 、module和exports
- 精通算法系列-二叉树路径
- ES6之Class的常用功能解读
- Android Studio 绑定下拉框数据(网络JSON数据)
- 捕获线程下的异常,对status变量减一
- C++11里shared_ptr源码剖析
- MySQL的binlog日志
- pthon_os模块
- MVC设置初始页时发生的无法找到资源的简单错误
- 国庆清北刷题冲刺班 Day5 下午
- Java调用Oracle存储过程和函数(三)
- 常用正则表达式集合及工具类
- 二维数组中查找
- VS2015常用快捷键