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. 前端面试题整理——VUE双向绑定原理

    VUE2.0和3.0数据双向绑定的原理,并说出其区别. 代码: <!DOCTYPE html> <html lang="en"> <head> ...

  2. python爬虫---爬取王者荣耀全部皮肤图片

    代码: import requests json_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win ...

  3. 安装PLSQLDeveloper

    1.点击.exe开始安装 2.选择安装路径点击下一步 3.点击finish 4.注册  ,打开新安装的plsql 如下: 点击关闭(现在是登录不上的) 点击help->Register 如下: ...

  4. MySQL---char和varchar的区别

    char和varchar的区别 char表示定长, 即长度固定. varchar表示变长, 即长度可变. 当输入数据的长度小于定义的长度时, char会用空格填充, 而varchar则按照实际长度存储 ...

  5. Kubernetes构建云原生架构-图解

  6. Python学习笔记.md

    Python学习笔记 1.变量类型 x=5 int x="ss" string x='a' string x=True bool #查看变量类型 type(x) 2.字符串常用操作 ...

  7. Win下GCC报错 error: ‘for’ loop initial declarations are only allowed in C99 mode

    ##报错## 用GCC编译for循环会出现以下错误 error: 'for' loop initial declarations are only allowed in C99 mode 如图所示: ...

  8. 关于Electron框架应用的安全测试

    Electron框架应用的安全测试 0.Electron相关简介 electron.js是一个运行时框架,它在设计之初就结合了当今最好的Web技术,核心是使用HTML.CSS.JavaScript构建 ...

  9. 2021.07.17 P4170 染色(区间DP)

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

  10. Emacs基础使用教程及常见命令整理

    前言:最近使用Emacs,因此整理了官方中文教程中的一些知识点和常用的命令,方便查阅使用. 对于用习惯Windows的人来说,想要入门Emacs不是一件特别容易的事,但好在Emacs提供了官方的教程文 ...