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. WordPress 网站开发“微信小程序“实战(二)

    原文链接:https://devework.com/wordpres...,转载请用明链注明来源,谢谢! 本文是"WordPress 开发微信小程序"系列的第二篇,本文记录的是开发 ...

  2. Exchange 2013 中 NDR 常见的失败返回状态代码

    增强状态代码 描述 可能的原因 其他信息 4.3.1 Insufficient system resources 发生内存不足错误.资源问题(例如磁盘已满)可能导致该问题.您可能会收到内存不足错误,而 ...

  3. c++对于c的拓展_引用的本质是指针常量

    本质:c++底层实现的指针常量(Type & ref =val; // Type *const ref =&val)

  4. UML中类关系表示与Java代码中的对应关系

    UML中类关系表示与Java代码中的对应关系 1. 类的UML表示法 上图中,Employee 类有两个String类型的私有属性和一个返回值为String类型public 方法 getName(); ...

  5. nginx location关于root、alias配置的区别

    一.首先优先级如下: = 表示精确匹配,优先级最高 ^~ 表示uri以某个常规字符串开头,用于匹配url路径(而且不对url做编码处理,例如请求/static/20%/aa,可以被规则^~ /stat ...

  6. Ubu18.0-NVIDIA显卡驱动重装

    //图片仅供参考,请勿代入 问题情况:电脑装了双系统,WIN10+Ubu,Ubu分辨率不稳定,经常发生变化 显卡型号:打开设备管理器进行查看 解决方法:重装NVIDIA显卡驱动 1.去英伟达官网下载自 ...

  7. ajax - 终结篇jsonp,防抖节流

    今天是我们最后一天ajax的学习,这次学完总可以去vue了吧,我不信还有什么拦路石,先不说其他的先看看今天的内容. 1. 首先是同源策略,什么叫做同源? 如果两个页面的协议.域名.端口都相同的话,我们 ...

  8. 从电路到UI系列之一——常见显示控制接口的认识

    引入 我之前有两方面的使用屏幕的案例.在做的模块上需要用到屏幕来显示的时候,全是SPI屏幕,并口屏幕和IIC屏幕.在研究了驱动(或者是绘图函数更加合适)之后,我发现其实他们就是直接写显存,这个显存在面 ...

  9. Ant Design Pro V5 与 IdentityServer 实现 Password 模式的登录

    最近处于休息状态,想趁着休息时间,为自己做一个后台. 后端框架选用了 Abp.之前公司使用了一些自研的框架,但由于人力资源有限,后期框架的升级及维护都是比较耗时,这次干脆直接使用Abp,即省心又能快速 ...

  10. 安卓记账本开发学习day1

    学习了一些简单的布局与界面设计