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相关推荐

  1. 通用解题法——回溯算法(理解+练习)

    积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...

  2. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  3. Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)

    1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...

  4. java局部变量全局变量,实例变量的理解

    java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...

  5. 智能文档理解:通用文档预训练模型

    预训练模型到底是什么,它是如何被应用在产品里,未来又有哪些机会和挑战? 预训练模型把迁移学习很好地用起来了,让我们感到眼前一亮.这和小孩子读书一样,一开始语文.数学.化学都学,读书.网上游戏等,在脑子 ...

  6. 熵,交叉熵,散度理解较为清晰

    20210511 https://blog.csdn.net/qq_35455503/article/details/105714287 交叉熵和散度 自己给自己编码肯定是最小的 其他的编码都会比这个 ...

  7. mapreduce理解_大数据

    map:对不同的数据进行同种操作 reduce:按keys 把数据规约到一起 看这篇文章请出去跑两圈,然后泡一壶茶,边喝茶,边看,看完你就对hadoop 与MapReduce的整体有所了解了. [前言 ...

  8. 文件句柄和文件描述符的区别和理解指针

    句柄是Windows用来标识被应用程序所建立或使用的对象的唯一整数,Windows使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等.Windows句柄有点象C语言中的文件句柄. ...

  9. 通俗理解条件熵-数学

    就是决策树里面选划分属性用到的计算 条件熵越小表示划分之后各个集合越纯净 前面我们总结了信息熵的概念通俗理解信息熵 - 知乎专栏,这次我们来理解一下条件熵. 我们首先知道信息熵是考虑该随机变量的所有可 ...

最新文章

  1. Numpy中矩阵运算
  2. Performance Prism
  3. NOIP2015年普级组试题 金币
  4. Git安装步骤+Mac终端配置
  5. php和xml区别,php和XML
  6. Java经纬度坐标转换到平面坐标
  7. 洛谷——P1554 梦中的统计
  8. NLP高阶实战必读:一文走遍完整自然语言处理流程 文章
  9. java泛型特点_Java泛型
  10. MySQL数据库卸载手册
  11. mysql索引失效的情况
  12. Revisiting ResNets: Improved Training and Scaling Strategies论文简述
  13. 笔记本电脑连不上WIFI
  14. 实验吧-web-天下武功唯快不破
  15. uchome 标签讲解
  16. eclipse导入spring源码二(丢失的spring-asm-repack和spring-cglib-repack)
  17. 遭遇Win32.Loader.c,Trojan.PSW.Win32.GameOnline,Trojan.PSW.Win32.AskTao等2
  18. php获取用户豆瓣电影,php代码获取豆瓣网上电影信息的简介
  19. Nuxt 引入外部CDN插件配置
  20. Python定时任务框架APScheduler快速入门

热门文章

  1. 如何向亲戚们解释人工智能可以干啥?
  2. ZooKeeper 源码和实践揭秘
  3. Spring Boot 无侵入式 实现 API 接口统一 JSON 格式返回
  4. 解读Java 8 中为并发而生的 ConcurrentHashMap
  5. 直观讲解一下RPC调用和HTTP调用的区别
  6. 机器学习实践:了解数据核心的通用方法!
  7. 华人科学家胡安明被判无罪!曾因「中国行动计划」被FBI紧盯两年,遭软禁18个月...
  8. 两大顶级AI算法一起开源!Nature、Science齐发Alphafold2相关重磅,双厨狂喜~
  9. 我,25岁,高中时创立的自动驾驶技术公司即将上市,估值34亿美元
  10. 生猛!PDF 版本 6000 页 Java 手册开放下载!