《EffectiveC++》读书笔记(3):资源管理
时间:2023-06-27 23:37:00来源:面包芯语

点击上方“C语言与CPP编程”,选择“关注/置顶/星标公众号”

干货福利,第一时间送达!

小伙伴们大家好,我是飞宇。


(相关资料图)

今天继续更新《Effective C++》和《C++并发编程实战》的读书笔记,下面是已经更新过的内容:

《C++并发编程实战》读书笔记(1):并发、线程管控

《C++并发编程实战》读书笔记(2):并发操作的同步

《Effective C++》读书笔记(2):构造/析构/赋值运算

《Effective C++》读书笔记(1):让自己习惯C++

所谓资源就是,一旦用了它,将来必须还给系统,包括最常使用的动态分配内存、文件描述符、互斥锁等等。由于异常、函数内多重回传路径、版本更改时遗漏等原因,任何时候都确保这一点是很难的。

本章总结了基于对象的一般化资源管理办法以及一些专属条款。严守这些做法几乎可以消除资源管理问题。

条款13、以对象管理资源

假设你有一个工厂函数用来获取一个动态分配对象,那么任何调用它的用户有责任删除这个对象:

上述some_function函数看似没有问题,实际上仍有很多情况会导致不会执行删除操作,例如某个过早的return、某个异常、多个版本后维护人员遗忘了这一点等等。

为了确保动态获取的资源一定会被释放,可以用对象来管理资源,将获取资源的行为放在构造函数中,将释放资源的行为放在析构函数中;那么,不论程序如何运行,一定会执行析构函数,一定会释放资源。这种做法称为RAII(Resource Acquisition Is Initialization,资源获取即初始化)。

标准库中的智能指针可以辅助管理资源,其中shared_ptr的资源可以共享,通过引用计数来控制行为,引用计数归零时删除资源,而unique_ptr独享资源。更多的使用与实现可以查阅cppreference。

条款14、在资源管理类中小心coping行为

对于管理堆对象来说,上文的智能指针已经足够。但是很多资源并非基于堆,需要自己实现一个RAII类来管理,这时就需要考虑一个问题:怎么处理拷贝?通常有两种思路:

1、禁止拷贝。很多资源被复制是不合理的,因此可以用条款6中的方法来禁止拷贝构造/拷贝运算符。

2、对底层资源使用引用计数法。有时我们希望保有资源直到最后一个用户使用完,这时就可以用shared_ptr代替裸指针来管理底层资源,用shared_ptr的删除器来控制资源的析构行为。

假设需要包装Mutex互斥器,目前只有lock、unlock两个函数。因为资源通过这两个函数来获取与释放,不是通过堆,所以需要自己实现RAII类。

不过也有一些其他做法,例如将拷贝操作实现为深拷贝、将拷贝操作实现为转移资源的拥有权等。

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

各类API往往要求访问原始资源,只提供了裸指针的接口,因此对于RAII类来说也应该提供一个“取得其所管理之资源”的方法。或许有些破坏了类的封装性质,但对于RAII类来说问题不大,因为根本上来说它只是为了管理资源的获取与释放。

至于如何访问原始资源,一般分为显式转换与隐式转换。

1、显式转换,例如shared_ptr的get函数。因为需要明确指定,所以比隐式转换更安全。

2、隐式转换,用法更自然,但可能出错

条款16、成对使用new和delete时要采取相同形式

当删除指针时,为了让delete知道要处理的是单个对象还是数组,如果new表达式使用[]则delete表达式也应使用,如果new没有使用则delete也不应使用。

此外,为了避免失误,最好不要为数组形式进行typedef/using。事实上,STL中的vector、array基本可以替代原生数组。

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

在函数传参时new一个指针再初始化智能指针是不安全的:

考虑上面这个函数调用,假设f()出现异常,则前面申请的内存将没处释放了。这种内存泄露的本质是当申请数据指针后,没有马上传给std::shared_ptr。

解决方法有两个:1、在函数调用前先用独立语句初始化shared_ptr,再传给函数。2、函数传参时使用make_shared来初始化智能指针,它只执行一次内存申请,更加异常安全。

你好,我是飞宇,本硕均于某中流985 CS就读,先后于百度搜索以及字节跳动电商等部门担任Linux C/C++后端研发工程师。

同时,我也是知乎博主@韩飞宇,日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。

我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会。

加个微信,打开另一扇窗

标签:

最新
  • 《EffectiveC++》读书笔记(3):资源管理

    点击上方“C语言与CPP编程”,选择“关注 置顶 星标公众号”干货福利,

  • 郴州旅游必去十大景点 郴州最值得旅游的景点有哪些-世界实时

    在郴州有着丰富的旅游资源,非常推荐小伙伴们前去游玩哦!那么就让我们

  • 世界微速讯:东方港湾:强烈谴责假冒但斌名义欺骗投资者的非法行为

    证券时报e公司讯,“东方港湾投资管理”微信号27日发布关于警惕冒充但

  • 科汇股份:6月26日融资买入121.11万元,融资融券余额5814.25万元|天天观天下

    6月26日,科汇股份(688681)融资买入121 11万元,融资偿还144 27万元

  • 联创电子:公司已经成为国内机器视觉产业链的重要供应商

    联创电子(002036)06月27日在投资者互动平台表示:机器视觉是公司一个

  • 全球动态:防雷插座有用吗?防雷插座和抗电涌插座有什么区别?

    防雷插座有用吗?防雷插座可以在一定程度上保护电器设备免受雷击的损

  • 全球连线|2023夏季达沃斯论坛准备工作基本就绪

    第十四届夏季达沃斯论坛将于6月27日至29日在天津举行,届时将有来自90

  • 龙虎山在哪里 龙虎山有哪些景点?

    想必现在有很多小伙伴对于龙虎山在哪里是什么方面的知识都比较想要

  • 40°C高温+强降雨再次来袭!北方气温或再次突破极值,新一轮大雨明天从四川盆地开启|世界新要闻

    今天(6月26日),华北平原、东北地区等地仍有高温出没,高温强度较前

  • 助力药企打造品牌优势 郑州仙佑为中小企业发展注入新活力_全球快资讯

    仙佑集团膏药贴牌代加工厂家了解到,近年来,随着健康意识的提高和

  • 猪肘子的做法是什么?猪肘子是哪个部位? 快讯

    猪肘子的做法是什么?1 将猪肘子切成块,放入开水中汆烫3分钟。2

  • 湖南交通违章查询平台(湖南交通违章122122)

    1、在交警部门的机动车辆的交通违法记录的平台上,是不可能出现你所要

  • 14.99万元起售 深蓝S7正式上市 天天速看

    2023年6月25日,深蓝汽车第二款量产车,深蓝S7正式上市。新车共推出纯

  • 今日热门!mouse的复数是什么_mouse的复数

    1、mouse的名词复数为mice。2、具体释义如下:mouse英[maʊs] 美[maʊs]  

  • 被吊销营业执照的企业名称还能使用吗?公司设立要满足哪些基本条件呢?|播报

    违反公司法规定,虚报注册资本、提交虚假材料或者采取其他欺诈手段隐瞒

  • 强降雨致江西49.1万人受灾 直接经济损失5.1亿元

    中新社南昌6月26日电(朱莹)江西26日起各地雨水明显减弱,本轮暴雨过程

  • 旅游
    • 集中清理杂草垃圾 持续整治路域环境_环球新资讯

    • 房产加名税介绍 如何办理房产证加名? |世界观焦点

    • 天天热推荐:资金来源不正银行卡被冻结怎么办?银行卡显示交易异常被冻结怎么办?

    • 还不上借呗了怎么办?协商延期技巧有哪些?-世界通讯