理解shared_ptrT
1、shared_ptr<T>解决什么问题?
auto_ptr有个局限,拥有权转移。这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行delete。shared_ptr就是为了解决这个问题。
2、shared_ptr怎么解决这个问题?和auto_ptr类似,除此之外,还有几点需要注意:
3、增加一个字段为引用计数,当引用计数为0的时候,执行delete。引用计数字段不能放在资源管理类中,为什么?
假设放到资源管理类中,每个资源管理对象都有一个refCount字段,共享一个资源的资源管理对象的refCount取值一样,但是怎么保持一致呢?因为这些对象之间没有关联。同时注意:这里不能把refCount字段声明为static,因为static意味着资源管理类的所有对象共享refCount,而当前的要求是一部分对象共享一个refCount,另一部分对象共享另一个refCount。因此,引用计数要和资源绑定在一起。也就是说,这里需要两层封装:第一层是u_ptr<T>类,对资源封装,增加refCount字段,负责delete。第二层是shared_ptr<T>,对u_ptr<T>封装,判断u_ptr对象的引用计数为0,执行u_ptr的析构方法,间接释放资源。
4、有些情况下,当引用计数为0 的时候,我们不想执行delete,而是其他操作,因此,还需要一个删除器,和引用计数同样的道理,删除器应该放在u_ptr中,这个删除器就是指向方法的指针。
5、auto_ptr的copy构造和copy赋值,要转移拥有权。而shared_ptr的copy构造,引用计数加1,copy赋值对原对象的引用计数减1,引用计数为0,执行delete,同时对rhs的引用计数加1。
6、析构的时候,引用计数减1,引用计数为0,才执行delete。
7、示例代码如下(不完整,只有一部分):
1 template <typename T> 2 class u_ptr 3 { 4 template <typename T> friend class shared_ptr; 5 private: 6 u_ptr(T* ptr):_ptr(ptr),refCount(1) 7 { 8 } 9 10 ~u_ptr() 11 { 12 delete _ptr; 13 } 14 15 T* _ptr; 16 int refCount; 17 }; 18 19 template <typename T> 20 class shared_ptr 21 { 22 public: 23 shared_ptr(T* ptr):_u_ptr_ptr(new u_ptr<T>(ptr)) 24 { 25 } 26 27 shared_ptr(shared_ptr<T>& rhs) 28 { 29 _u_ptr_ptr= rhs._u_ptr_ptr; 30 ++_u_ptr_ptr->refCount; 31 } 32 33 shared_ptr& operator=(shared_ptr<T>& rhs) 34 { 35 if(this!=&rhs) 36 { 37 if(--_u_ptr_ptr->refCount ==0) 38 { 39 delete _u_ptr_ptr; 40 } 41 _u_ptr_ptr= rhs._u_ptr_ptr; 42 ++_u_ptr_ptr->refCount; 43 } 44 return *this; 45 } 46 47 ~shared_ptr() 48 { 49 if(--_u_ptr_ptr->refCount ==0) 50 { 51 delete _u_ptr_ptr; 52 } 53 } 54 55 private: 56 u_ptr<T>* _u_ptr_ptr; 57 };
理解shared_ptrT相关推荐
- 通用解题法——回溯算法(理解+练习)
积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...
- stream流对象的理解及使用
我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...
- Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)
1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...
- java局部变量全局变量,实例变量的理解
java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...
- 智能文档理解:通用文档预训练模型
预训练模型到底是什么,它是如何被应用在产品里,未来又有哪些机会和挑战? 预训练模型把迁移学习很好地用起来了,让我们感到眼前一亮.这和小孩子读书一样,一开始语文.数学.化学都学,读书.网上游戏等,在脑子 ...
- 熵,交叉熵,散度理解较为清晰
20210511 https://blog.csdn.net/qq_35455503/article/details/105714287 交叉熵和散度 自己给自己编码肯定是最小的 其他的编码都会比这个 ...
- mapreduce理解_大数据
map:对不同的数据进行同种操作 reduce:按keys 把数据规约到一起 看这篇文章请出去跑两圈,然后泡一壶茶,边喝茶,边看,看完你就对hadoop 与MapReduce的整体有所了解了. [前言 ...
- 文件句柄和文件描述符的区别和理解指针
句柄是Windows用来标识被应用程序所建立或使用的对象的唯一整数,Windows使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等.Windows句柄有点象C语言中的文件句柄. ...
- 通俗理解条件熵-数学
就是决策树里面选划分属性用到的计算 条件熵越小表示划分之后各个集合越纯净 前面我们总结了信息熵的概念通俗理解信息熵 - 知乎专栏,这次我们来理解一下条件熵. 我们首先知道信息熵是考虑该随机变量的所有可 ...
最新文章
- Numpy中矩阵运算
- Performance Prism
- NOIP2015年普级组试题 金币
- Git安装步骤+Mac终端配置
- php和xml区别,php和XML
- Java经纬度坐标转换到平面坐标
- 洛谷——P1554 梦中的统计
- NLP高阶实战必读:一文走遍完整自然语言处理流程 文章
- java泛型特点_Java泛型
- MySQL数据库卸载手册
- mysql索引失效的情况
- Revisiting ResNets: Improved Training and Scaling Strategies论文简述
- 笔记本电脑连不上WIFI
- 实验吧-web-天下武功唯快不破
- uchome 标签讲解
- eclipse导入spring源码二(丢失的spring-asm-repack和spring-cglib-repack)
- 遭遇Win32.Loader.c,Trojan.PSW.Win32.GameOnline,Trojan.PSW.Win32.AskTao等2
- php获取用户豆瓣电影,php代码获取豆瓣网上电影信息的简介
- Nuxt 引入外部CDN插件配置
- Python定时任务框架APScheduler快速入门
热门文章
- 如何向亲戚们解释人工智能可以干啥?
- ZooKeeper 源码和实践揭秘
- Spring Boot 无侵入式 实现 API 接口统一 JSON 格式返回
- 解读Java 8 中为并发而生的 ConcurrentHashMap
- 直观讲解一下RPC调用和HTTP调用的区别
- 机器学习实践:了解数据核心的通用方法!
- 华人科学家胡安明被判无罪!曾因「中国行动计划」被FBI紧盯两年,遭软禁18个月...
- 两大顶级AI算法一起开源!Nature、Science齐发Alphafold2相关重磅,双厨狂喜~
- 我,25岁,高中时创立的自动驾驶技术公司即将上市,估值34亿美元
- 生猛!PDF 版本 6000 页 Java 手册开放下载!