C++中的资源管理非常重要,在将资源加载到内存后,便可以使用资源了,当我们不再需要资源时,我们要保证其正确的释放,才能将其占用的内存空间归还给操作系统,不正确的释放很容易造成内存泄漏。本章以资源管理类为基础,提出了以下几条准则,这章内容比较简单,大概总结一下:

13. 以对象管理资源

绝大多数资源都是动态分配于堆内存之中,然后被用于某个局部范围区域内。这类资源应该在控制流离开该区域时被释放,或者全局资源在退出main函数时也应该释放。通常我们用new创建一个堆对象,最在使用完对象后用delete完成销毁释放,在创建后销毁前期间,如果发生函数提前退出或者对象指针被重置,则相应的堆内存就无法释放了。智能指针是一种指针管理类,它可以执行几乎所有裸指针能执行的操作,而且智能指针在离开作用域时会自动调用所指对象的析构函数,所以用智能指针对象来管理资源的指针是一个非常好的选择。一个很简明的原则就是:资源获取时便进行初始化————RAII。即一个获取的资源在获得时就应该被放进资源管理类(智能指针)中,并在资源管理类析构的时候完成资源释放。例如:std::shared_ptr<OneClass> p_oneclass(new OneClass(666)),这种写法能够保证在适当的时候正确释放对象。

PS:当然,无脑使用智能指针也不好,在调试代码的时候,无法直接看到智能指针所指对象的成员状态,不利于修bug。

14. 在资源管理类中小心copy行为

如果需要复制RAII对象,那么也请完全复制其管理的资源,但资源我们一般都是读取,所以更好的选择是抑制copy行为,在copy时实施引用计数,当引用计数为0时,执行析构释放资源。总之就是使用std::shared_ptr管理对象。

15. 在资源管理类中提供对原始资源的访问

这是为了适配需要访问原始资源的接口,所以智能指针提供了一个.get()接口返回其管理的裸指针。但需要明确的是,获取的裸指针只用来访问资源,不应对该指针执行delete,因为释放操作是授权给智能指针的。多次释放会导致非法释放内存错误。

16. 成对的使用new和delete时,要采用相同的形式

这个很简单,即构造一个对象,调用new构造,调用delete释放。构造对象数组,调用new Array[]构造,调用delete[] Array释放。

17. 以独立语句将newed对象置入智能指针

① 智能指针的构造函数是explicit的,即不会对输入参数进行隐式转换;

还是为了防止内存泄漏,以独立语句将newed对象置入智能指针,即std::shared_ptr<OneClass> p_oneclass(new OneClass(666))单独一行。因为如果这样使用int ret = Fun(std::shared_ptr<OneClass>(new OneClass(666)), other_func()), 编译器有可能将other_func()的执行放在new完对象和构造智能指针对象之间,如果此时other_func()抛出异常,那么指向资源的指针会丢失,造成内存泄漏。

小结:将你不知道该何时释放的对象放入智能指针管理。

《Effective C++》阅读总结(三):资源管理的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  3. 【原】SDWebImage源码阅读(三)

    [原]SDWebImage源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1.SDWebImageDownloader中的downloadImageWithURL 我们 ...

  4. Effective C++(第三版)笔记 ---- 第一部分让自己习惯C++

    内容从侯捷译版的<Effective C++>(第三版)摘录 条款一 C++作为一个多种范式融合的语言,可以看成是语言的联邦,它包含了一下四种主要的次语言: C.C++以C为基础,很多时候 ...

  5. 【详解】ThreadPoolExecutor源码阅读(三)

    系列目录 [详解]ThreadPoolExecutor源码阅读(一) [详解]ThreadPoolExecutor源码阅读(二) [详解]ThreadPoolExecutor源码阅读(三) 线程数量的 ...

  6. Redis源码阅读(三)集群-连接初始化

    Redis源码阅读(三)集群-连接建立 对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供 ...

  7. Effective C++ 笔记三 资源管理

    条款13:以对象管理资源 许多资源被动态分配于heap内而后被用于单一区块或函数内.它们应该在控制流离开那个区块或函数时被释放.标准程序库提供的auto_ptr正是针对这种形式而设计的特制产品.aut ...

  8. 《Effective C++》第三版笔记

    阅读此笔记前,请先阅读 <Effective C++>第二版笔记  和  <More Effective C++>笔记 这里只记录与上面笔记不同的条款,主要是 "面对 ...

  9. Effective Java 阅读笔记——方法

    38:检查参数的有效性 每当编写方法或者构造器的时候,应该考虑它的参数有哪些限制,在方法的开头处对参数进行检查,并且把这些限制写入文档. 注意: 对于公有方法,应该使用@throws标签在文档中说明违 ...

  10. SDWebImage源码阅读-第三篇

    这一篇讲讲不常用的一些方法. 1 sd_setImageWithPreviousCachedImageWithURL: placeholderImage: options: progress: com ...

随机推荐

  1. 前端每日实战:133# 视频演示如何用 CSS 和 GSAP 创作有多个关键帧的连续动画

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/eLMKJG 可交互视频 此视频是可 ...

  2. SQLite实现用户数据存储+Android之app:lintVitalRelease解决办法

    今日所学 SQLite实现用户数据存储 遇到的问题 界面没能显示出存在数据库中的信息 明日计划 查找界面没能显示出存在数据库中的信息的原因 报错:app:lintVitalRelease 解决办法: ...

  3. What are PCIe Slots

    https://www.hp.com/us-en/shop/tech-takes/what-are-pcie-slots-pc What are PCIe Slots and How Can I Us ...

  4. MySQL 集群历史版本信息

    MySQL 集群有两种命名方式,在Mysql5.1版本之前,MySQL 集群是以MySQL版本号命名:MySQL5.1(包括)之后开始以 mysql-mysql_server_version-ndb- ...

  5. 帝国CMS模板$GLOBALS[navclassid]用法详解

    帝国CMS模板程序扩展变量说明:通过这些变量可实现各种更复杂的显示格式. 一.列表/封面模板变量说明:(栏目页或专题页中使用) (一).当前栏目ID或专题ID:$GLOBALS[navclassid] ...

  6. 计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统

    系列的上一篇计算机系统4-> 计组与体系结构1 | 基础概念与系统评估,学习了一些计算机的基础概念,将一些基本的计算机组成部分的功能和相互联系了解了一下,其中很重要的一个抽象思想就是软硬件的接口 ...

  7. 2021.07.17 P4170 染色(区间DP)

    2021.07.17 P4170 染色(区间DP) [P4170 CQOI2007]涂色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.目标状态可以由哪些状态转移过来. ...

  8. 在 WinForms 项目中使用全局快捷键

    借助于全局快捷键,用户可以在任何地方操控程序,触发对应的功能.但 WinForms 框架并没有提供全局快捷键的功能.想要实现全局快捷键需要跟 Windows API 打交道.本文就交你如何使用 Win ...

  9. 论文解读(GCC)《Graph Contrastive Clustering》

    论文信息 论文标题:Graph Contrastive Clustering论文作者:Huasong Zhong, Jianlong Wu, Chong Chen, Jianqiang Huang, ...

  10. 解决anaconda3打开不了闪退

    今天想新创个环境,结果发现创不起,而且anaconda居然也进不去了. 然后尝试了网上各种方法,修改c:user/用户/用户名目录下的.condarc文件,镜像源,包括重装都没用. 最后 把.cond ...