*以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/7A9-tGZxf4w_7eZl3OUQ4A
(资料图片)
学过 Java、C# 或者其他托管语言(managed languages)的同学,回过头来看 C++ 的时候,第一反应就是 C++ 没有自动垃圾回收器(GC),而不能充分利用的资源被称为垃圾。
那么 C++ 真的不能自动回收垃圾吗?带着这个疑问我们来看看一般 C++ 程序都是怎样回收资源的。
内存在计算机系统中是有限的资源,通常申请内存和释放内存是这样子的,假设有个被调用的函数 function():
void function(){ int *p = new int; // 申请内存 // 资源申请下来了,不玩有个 p 用? // do something delete p; // 释放内存}
这段示例代码在 function() 函数开始的时候申请了一块内存,大小对应于 int 类型,然后在函数结束的时候释放它。通常来说,这看起来很OK,没毛病,但是,如果遇到了下面几种情况呢?
程序如果中途有逻辑让它提前退出 function() 函数发生了异常而没有被捕获到那么在函数尾部执行释放内存的动作有几率不会被执行,意味着发生也会内存泄漏。像上面这段代码,如果调用的次数不多也不碍事,不过,如果循环调用 function(),这时泄露的内存资源会不断累积,而且一直被浪费掉,期间系统无法再次使用这些被浪费的内存,直到进程被终止,严重的话,会导致系统资源被耗尽,跑着跑着系统都崩溃了。这种 bug 在 C 范式的编程语言中真的很常见。
RAII 是什么众所周知 C++ 具有面向对象的特性,在初始化类对象的时候,系统会调用类构造函数。如果类对象是存放在栈空间的话,比如声明为局部变量,那么当类对象超出生命周期时,比如退出局部变量的作用域,系统会调用这个对象的类析构函数;如果类对象是存放在堆空间的话,比如通过 new 操作符创建的类对象,那么当类对象被销毁时,比如对对象执行 delete 操作,系统同样会调用类析构函数。
C++ 的这个特性可以用来解决上面提到的资源泄露问题,怎么利用呢?
modern C++ 实践建议优先把资源存放在栈上。如果只是个变量类型,完全可以用局部变量的形式定义声明,这样代码块在退出后系统自动回收栈上的资源。
对上面的函数 function() 修改
void function(){ // 声明定义为局部变量,资源存储在栈区 int data = 0; // do something with data // 函数退出时,自动释放 data 占用的空间}
当资源比较占空间时,需要在堆上分配资源,可以通过指针引用它,资源的申请放在类的构造函数里,然后在析构函数里释放。下面举个例子
class Helper{private: int* data;public: Helper() { data = new int; // 在堆上申请内存 } ~Helper() { delete data; // 释放堆上申请的内存 } void do_something_with_data() {}};void function(){ // 声明定义为局部变量,对象存储在栈区 // 调用 Helper 类构造函数在堆上申请资源 Helper help; // 通过对象 help 调用成员 data // 如果 data 是 Helper 私有成员 // 在类外面必须通过类成员方法调用 data help.do_something_with_data(); // 函数退出时,自动释放 help 对象占用的栈空间 // 就算发生了异常或者中途退出都会执行这一步 // help 对象被销毁时,调用 Helper 类析构函数 // Helper 类析构函数释放已申请的堆上资源}
利用这种特性的行为被 C++ 发明人称呼为 RAII,英文全称是「resource acquisition is initialization」,中文翻译过来是「资源获取即是初始化」。而我喜欢把它叫做上下文管理,实现资源申请释放的类叫做上下文管理器(context manager)。
经典实践--智能指针上面的示例代码写起来略显啰嗦,为了推广这种设计核心思路和简化代码编写,在 C++ 11 之后标准库里添加了 unique_ptr。
unique_ptr 属于 Smart Points 中的一种,Smart Points 在国内通常翻译为「智能指针」。智能指针负责管理和释放资源。上面的 function() 函数可以改成这样子
#include void function(){ // 实例化智能指针对象,输入需要被管理的内存首地址 // 对象为局部变量,存储在栈区 std::unique_ptr data(new int); // 智能指针对象就像普通指针一样调用 printf("data=%d\n", *data); // 函数退出时,自动释放 data 对象占用的栈空间 // 就算发生了异常或者中途退出都会执行这一步 // data 对象被销毁时,同步释放被管理的内存资源}
可见,用了智能指针后,不需要像之前那样定义类 Helper (上下文管理器)了,代码清爽很多。
不过,上面的示例代码中有个地方需要注意,在实例化智能指针对象时必须传入内存地址,有没有其它更好的方式设置被管理的内存地址?
有的,C++ 14 之后标准库添加了 make_unique,演示一下怎么用
std::unique_ptr data = std::make_unique();
荐书活动编程的设计思想是一门很有意思的事情,其中有一门前人总结得很到位的学问叫「设计模式」,想深入了解吗?
最近在联合机械工业出版社搞荐书活动,这次参与活动的图书是《深入理解设计模式》,作者是林祥纤。
其中有几本样书,八戒 想送给读者朋友,需要免费领取图书的朋友可以点击文章抬头的原文链接!
图书简介:
本书以作者与虚拟女友(小璐)在生活中遇到的各种问题作为主线,引出设计模式的各种功能、用途,以及解决方法,系统介绍了23种设计模式,根据具体的实例形象化、具体化地进行了代码的编写和详细讲解,让那些本来对设计模式不太了解、一知半解、只有概念的读者,彻底了解和掌握常用的设计模式使用场景及使用方式,并掌握每个设计模式的UML结构和描绘方式。
本书共23章,包括认识设计模式、单例模式、工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式、代理模式、策略模式、命令模式、状态模式、模板方法模式、备忘录模式、中介者模式、观察者模式、迭代器模式、责任链模式、访问者模式、解释器模式。
通过以上的知识,让你从模式小白直接升级为模式大神!本书所需源代码,均可通过本书配套下载链接获得。 本书适合编程初学者或希望在面向对象编程上有所提高的开发人员阅读。
上一篇:今年前4个月广东城镇新增就业累计41.62万人|全球热议
下一篇:最后一页
学过Java、C 或者其他托管语言(managedlanguages)的同学,回过头来看C++的时候,第一反应就是C++没有自动垃
自2015年以来,心理健康应用Koko一直试图为有需要的人提供支持。当有人给应用程序发短信,诉说自己的愧疚或
韩国科学技术研究院科学家展示了使用3D打印成功制造出的可导电弹性组件。他们在《自然·电子学》的一篇...
招聘活动现场(资料图)广州人才集团供图中新网广州5月16日电(记者程景伟)广东省人力资源和社会保障厅16日举
1、最少增加6个面的面积2x2x6=24平方分米。
今天小编肥嘟来为大家解答以上的问题。怎么在小红书上卖东西,网上什么东西最好卖相信很多小伙伴还不知道,
1、原莱格兰德共和国的贵族,也是克拉斯特学院的毕业生,原学生会长。2、为了恢复母国的尊严,举起了推翻古
5月18日北京大觉寺国际博物馆日免费向公众开放通知尊敬的观众朋友:在5·18国际博物馆日即将来临之际,...
5月20日北京太平洋海底世界双人优惠票:158元【购买】使用说明:使用时需持个人有效证件身份证,和手机验证码
1、楼主,你好!!你给个订单编号查询不到任何东西的,订单编号是团购网对每笔订单的编号。2、不登录账号,
1、不需要的。2、需要专家论证的脚手架工程:搭设高度50m及以上落地式钢管脚手架工程。3、2、提升高度150m
小伙伴们,你们好,今天小夏来聊聊一篇关于魏起,关于魏起简述的文章,网友们对这件事情都比较关注,那么现
18点08分!辽媒爆料辽篮夺冠巡游暂时取消,取消巡游的原因被曝光,辽篮,辽媒,cba,张镇麟,辽宁飞豹
这一次在乌克兰上空,俄军“匕首”与乌克兰“爱国者”展开了激烈的攻防,估计全世界都在瞪大眼睛观看这...
沙特和阿联酋为什么会转向,第一是他们确实有更好的选择,没必要被美国支配;第二是美国的承诺就跟废纸一样
第一时间提供各大券商研究所报告,最大程度减少个人投资者与机构之间信息上的差异,使个人投资者更早的了解
据法媒footmercato报道,国米与马竞竞争多特的葡萄牙边翼卫格雷罗。报道称,国米今夏仍将继续关注自由转会
国米在本轮欧冠总比分3-0淘汰米兰,成功晋级决赛。数据统计显示,国米本赛季将共计参加3场决赛(意超杯、意
今天,A股极度缩量,马上要见底了?,a股,港股,个股,大盘,券商股,深股通,板块跌幅
国际局势风云变幻,每天都有很多令人始料不及的事情发生,而近日,美国对华态度的突然反转甚至是翻脸,无疑
不过每天喝汤属实也腻了,想到之前各种蒸菜的做法,搭配一条新鲜的猪颈肉,只要简单调味,上锅一蒸!最后水
中证网讯(记者张枕河)5月17日,瑞银发布最新报告表示,虽然当前的宏观不确定性使美元受益,但该机构保持不
扁平化管理是一种基于权利分散、信息共享、协作发展的组织管理方式,其核心理念是减少层级、简化流程、增强
预计阅读时间6分钟。尽管经过几个世纪的研究,宇宙和我们的星球,仍然笼罩在神秘之中。我们收集事实、形成
1、有两个方法右键或CTRL+1--设置单元格格式-边框--然后选择相应的斜线2、工具栏上面的边框快捷按钮--点击旁边的
广告
X 关闭
广告
X 关闭