用ScopeGuard简化异常安全代码

每天进步一点点——C++11中使用lambda表达式实现一个简单的ScopeGuard C++11编程中一个简单实用的ScopeGuard实现 阅读详情

ScopeGuard是Loki库里的一个组件,用来在c++中进行局部资源管理。

很多时候,在一个函数内部会有资源的申请和释放,如果在函数内部出现的异常,那么要完全释放资源是比较痛苦的,常见的作法是对所有可能产生异常的地 方try...catch,不管是否有异常,申请的资源都是要释放的。但是这样的写法造成代码体积很大,而且很不易读。解决的方法是使用c++的 RAII(资源申请即初始化),可以对每个资源的申请和释放封装一个类,在类的构造函数中申请,析构函数中释放,这样只要在使用的函数内部生成这个对象的 一个实例,不论是否产生异常,编译器都会调用析构函数释放资源了。

不过这个方法不好的地方是,会产生一大堆很小的类,看起来肯定是不舒服,用起来也很不方便。

ScopeGuard用了一组模板类来代替对每个资源的申请/释放的一大堆小类。ScopeGuard实现的机制是,保存一个用于释放资源的函数在 ScopeGuard内部,当ScopeGuard析构(也就是作用域结束)时,在ScopeGuard的析构函数中调用保存的函数实现资源释放。如果在 析构之前调用了ScopeGuard对象的Dismiss()方法,那SocpeGuard就不再执行保存的函数。

ScopeGuard支持两种方式,一种是保存一个函数指针,另一种是保存了类成员函数。这在ScopeGuard内部分别通过 ScopeGuardImp和ObjScopeGuardImp来实现。它们都有一个共同的基类ScopeGuardImpBase,基类集中了对 dismissed_标志的管理。在ScopeGuard的析构函数中,会通过判断dismissed_标志来决定是否调用保存的函数。

在Loki库中,实现了6个ScopeGuardImp类,分别是ScopeGuardImp0, ScopeGuardImp1, ScopeGuardImp2, ScopeGuardImp3, ScopeGuardImp4, ScopeGuardImp5,它们的区别在于析构时要执行的函数参数个数不一样,ScopeGuardImp0用于没有参数的情 况,ScopeGuardImpl用于一个参数的情况...ScopeGuardImp5用于5个参数的情况。一般也不会有这么多参数的函数,如果确实碰 到了,那就自己实现吧。

对于ObjScopeGuardImp一共实现了4个类,分别是ObjScopeGuardImp0, ObjScopeGuardImp1, ObjScopeGuardImp2, ObjScopeGuardImp3,它们的区别也是在参数的个数上。ObjScopeGuardImp和ScopeGuardImp的区别在 于,ObjScopeGuardImp用于保存了一对象以及一个类成员函数,在析构的时候,会通过这个对象调用它的成员函数。它使用了不太为人所知的语 法:指向成员函数的指针和operator.*()。

直接使用上面这些类是很麻烦的,你必须自己记住有几个参数,各个参数的类型,然后生成这个类的实例。幸亏Loki提供了两个辅助函 数:MakeGuard和MakeObjGuard,故名思义,前一个用于生成ScopeGuardImp对象,后一个用于生成 ObjScopeGuardImp对象。MakeGuard和MakeObjGuard依靠编译器自动推导函数的参数,不再需要显式地创建对象。这个技巧 也被用于标准库中,如make_pair和bind1st。

MakeGuard和MakeObjGuard通过一个临时对象的引用的技巧来简体操作。根据C++标准,如果const的引用被初始化为对一个临 时变量的引用,那么它会使这个临时变量的生命期变得和它自己一样。这在"关于临时对象的引用"一文中有过描述。ScopeGuard被定义为 typedef const ScopeGuardImplBase& ScopeGuard,MakeGuard和MakeObjGuard虽然生成不同的ScopeGuardImpBase子类对象,但是都被赋给了 const ScopeGuardImplBase&这个基类对象的引用,这个临时对象的生命周期就会变成和这个基类引用的生命周期一致。这样就不用在 MakeGuard和MakeObjGuard的返回值的地方手写类型。

也就是说,MakeGuard和MakeObjGuard的返回值,必须要有一个值来存储,否则它返回的地方就析构了。

所以,ScopeGuard中定义了两个宏来简化返回值的操作,使用宏LOKI_ON_BLOCK_EXIT和LOKI_ON_BLOCK_EXIT_OBJ的话,会自动通过__LINE__生成一个不会相同的返回值。

RK3588平台SDIO WiFi模组调试全流程:从设备树到网络连通 嵌入式Linux开发中,SDIO接口WiFi模组的驱动移植与调试是连接硬件与网络的关键环节。其原理涉及SDIO总线枚举、设备树硬件描述、电源时序控制、固件加载及网络协议栈协同。技术价值在于实现稳定无线连接,支撑边缘计算、工业网关等场景的数据回传与远程运维。应用场景包括智能NVR、无线图传等。本文以RK3588与aic8800模组为例,完整覆盖硬件确认、设备树配置、驱动编译、固件加载及网络验证,提供可复用的调试路径与排查经验。 阅读详情

相关推荐

scope_guard:一种易于使用但难以滥用的现代C ++范围保护

scope_guard:一种易于使用但难以滥用的现代C ++范围保护

Android源码分析 - init进程

本篇以android-11.0.0_r25作为基础解析PC启动会通过BIOS引导,从0x7c00处找到以0xaa55为结尾的引导程序启动。而Android通常使用在移动设备上,没有PC的BIOS,取而代之的是BootLoader。在CPU上电复位完成后,会从一个固定的地址加载一段程序,即BootLoader,不同的CPU可能这个地址不同。BootLoader是一段引导程序,其中最为常见的为U-boot,它一般会先检测用户是否按下某些特别按键,这些特别按键是uboot在编译时预先被约定好的,用于进入调试模式。

qq_34231329的博客 1236

ScopeGuard:仅标头的现代C ++ ScopeGuard工具可提供多种用法,这些用法简单易用

ScopeGuard 仅标头的现代C ++ ScopeGuard工具可提供多种用法,这些用法简单易用。 注意:即将完成,但需要更多测试。 简单的例子 有3种使用ScopeGuard的方法: 将离开当前作用域时执行的代码放在代码块ON_SCOPE_EXIT {}中。 # include " ScopeGuard.h " ... { ... ON_SCOPE_EXIT{ // callback statments // such as releasing resources }; ... } // callback statments are executed at this point 放在SCOPEGUARD()中可调用 ... { void my_callback (); ... SCOPE

Android System.loadLibrary深度剖析

Android System.loadLibrary深度剖析 缘起: 从Android 6.0 & AGP 3.6.0开始,系统支持直接加载apk中未压缩的so,也就是说在App安装时,系统不再将apk中的so解压,而在加载so时,直接从apk中加载。 具体见:https://developer.android.com/guide/topics/manifest/application-element#extractNativeLibs 然而,熟悉glibc开发的程序员知道,dlopen系列函数不支

胡超的学习日志 7359

深入解析Android14应用安装权限:从声明到授予的完整适配指南

本文深入解析Android14应用安装权限的适配方法,重点介绍了从权限声明到授予的完整流程。与Android13相比,Android14在权限管理机制上进行了重要调整,特别是通过AppOpsManager实现权限的对象化封装。文章详细讲解了权限声明的基础配置、Framework层适配方案、运行时权限授予方法以及常见问题排查指南,帮助开发者高效完成Android14权限适配。

o9p0q1的博客 695

MATLAB锂离子电池伪二维(P2D)模型实现

锂离子电池伪二维(P2D)模型的MATLAB实现。该模型基于Newman等人提出的经典电化学模型,考虑了固液相扩散、电荷守恒和电化学反应动力学。

hie98894的博客 1930

使用ScopeGuard在运行环境中监测内部变量

使用ScopeGuard在运行环境中监测内部变量smilemac1. ScopeGuard简介我们知道,使用结构化异常来书写一个期望有较高可靠性的函数时,尤其这段函数如果有副作用(side effect),那么在执行失败,需要保持资源一致性的时候,琐碎凌乱的try块会使程序可读性很差,并且看上去很丑陋,Petru Marginean和Andrei Alexandrescu所写的Scop

Peter Chang 的专栏 1325

OpenWebUI外部模型配置异常排查与修复指南

本文详细解析了OpenWebUI外部模型配置异常的常见问题及解决方案,包括隐藏字符、数据库锁死等典型现象。通过错误日志分析和数据库修复实战指南,帮助开发者快速定位并解决配置问题,确保OpenWebUI与第三方大模型的稳定连接。

weixin_29205061的博客 312

简化异常安全代码

尽管有点自卖自夸,我还是要在一开始就告诉你,这篇文章里有精彩内容。因为我说服我的好朋友Petru Marginean和我合作写这篇文章。Petru开发了一个对处理异常很有用的库。我们一起改进其实现,由此我们得到一个精炼的库,在特定的情况下,它可以大大简化异常安全代码的编写。 在有异常的情况下要写出正确的代码不是一件容易的事,让我们一起来面对它。异常建立了一个单独的控制流,它和应...

weixin_30653097的博客 100

基于Web的智能家居(源码+开题)

实践上,智能家居系统的普及和应用将极大改善人们的居住体验,提高生活质量,同时也有助于促进智能家居产业链的发展和完善,为社会经济发展注入新的活力。此外,本研究还将对基于Web的智能家居系统的用户体验进行深入研究,通过用户调研和数据分析,不断优化系统功能和界面设计,提升用户的使用体验和满意度。针对以上问题,本研究将综合运用物联网、云计算、大数据等新一代信息技术,通过系统架构设计、功能模块开发、安全性保障、用户体验优化等多个方面的研究工作,力求为基于Web的智能家居系统的研发和应用提供全面而有效的解决方案。

sryue06的博客 1904

使用Label Studio标注车牌数据:YOLOv26模型训练指南

在计算机视觉领域,数据标注是模型训练的基础环节,直接影响最终模型的识别精度。Label Studio作为专业的标注工具,支持多种标注类型和格式导出,特别适合目标检测任务的数据准备。通过多边形标注技术,可以精确捕捉车牌的四个角点,生成旋转矩形框(OBB)标注数据,这种标注方式相比传统水平框能更好地处理倾斜车牌场景。标注完成后,数据可导出为YOLO格式,直接用于YOLOv26等先进目标检测模型的训练。在实际工程中,合理的标注策略和严格的质量控制能显著提升车牌识别模型在复杂场景下的鲁棒性,适用于智能交通、停车场管

chuozhi7142的博客 904

C++黑魔法系列之ScopeGuard源码剖析

到此,ScopeGuard源码的剖析就圆满结束了,奇怪的知识又增加了!值得注意的是:行文中的代码和Folly源代码的实现会有些细微差别,一些平台/语言标准版本的兼容代码也被我简化了,一些细节处也统一用了C++17的惯用法。拜读大师级作品,掌握C++黑魔法,以雷霆、击碎黑暗!

木牛的博客 183

手把手教你学Simulink--基于未来出行解决方案的场景实例:电动飞行汽车(eVTOL)的动力系统建模与仿真

电动垂直起降飞行器零道路拥堵:三维空间飞行绿色低碳:全电驱动,零排放快速响应:城市内15分钟直达低噪音:相比直升机↓20dB📊 预测:2030年全球eVTOL市场规模将超300亿美元,中国、美国、欧洲加速适航认证。本文通过,构建了电动飞行汽车(eVTOL)动力系统高压电池系统建模电力电子(DC-DC、逆变器)实现PMSM电机+螺旋桨推进系统搭建完整飞行任务动态仿真性能KPI评估与优化。

MHD0815的博客 443

Generic:简化异常安全代码

    尽管有点自卖自夸,我还是要在一开始就告诉你,这篇文章里有精彩内容。因为我说服我的好朋友Petru Marginean和我合作写这篇文章。Petru开发了一个对处理异常很有用的库。我们一起改进其实现,由此我们得到一个精炼的库,在特定的情况下,它可以大大简化异常安全代码

914

【光子AI 2026 企业级 Agent 架构指南】别再把 Skill 当 Tool:Agent Skills × MCP 企业级落地全指南(最新定义澄清 + 场景大全 + 选型决策树+安全工程清单)

摘要: 2026年企业级AI架构迎来两大核心标准——Agent Skills与MCP(Model Context Protocol),分别解决流程标准化与系统集成难题。Agent Skills通过“文件夹化能力包”(SOP+脚本+模板)固化专家流程,确保输出一致性;MCP则以类USB-C的协议统一外部系统接入,降低集成成本。两者差异显著:Skills专注程序性知识(如财报生成),MCP侧重动态连接(如跨平台数据调用)。实际场景中,复杂需求(如智能客服)需组合使用——MCP为骨架提供连接能力,Skills为大

AI天才研究院 2476

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Generic<Programming>:简化异常安全代码

发信人: meteors (刘欣), 信区: C  标  题: Generic:简化异常安全代码  发信站: BBS 碧海青天站 (Mon Jan  3 13:24:55 2005), 转信        编者按:这是Generic系列中又一篇极好的文章。资源管理一直是程序设计中挥之不去的阴影,而其中最常见的就是资源泄露问题。以Java为代表的语言引入了垃圾收集(Garbage Coll

529

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

永久改变你写异常安全代码的方式(神奇的Loki::ScopeGuard)

转自 http://blog.youkuaiyun.com/purewinter/article/details/1860875   作者:Andrei Alexandrescu and Petru Marginean 原文地址:http://www.ddj.com/cpp/184403758 翻译,裁剪,修改:purewinter 注:裁剪修改只是为了让更多csdn上的读者不会因为此文太长而放弃阅

xiaodan007的专栏 2104

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

编程日记: 学习:Generic<Programming>:简化异常安全代码

转自:http://blog.youkuaiyun.com/mseaspring/article/details/1817417   尽管有点自卖自夸,我还是要在一开始就告诉你,这篇文章里有精彩内容。因为我说服我的好朋友Petru Marginean和我合作写这篇文章。Petru开发了一个对处理异常很有用的库。我们一起改进其实现,由此我们得到一个精炼的库,在特定的情况下,它可以大大简化异常安全代码的编写。

andyjim的专栏 617

c++异常处理第四篇---不使用try catch语句,使用Loki::ScopeGuard

转载:神奇的Loki::ScopeGuard2011-07-05 12:52:05 分类:C/C++ 转载:http://blog.youkuaiyun.com/fangqu/article/details/4242245 ---------------------------------------------------------------------...

weixin_30508309的博客 199

c++中如何实现事务

c++中如何实现事务(1) (2006-04-17 17:50:43) 转载▼   分类: 技术 【c++中如何实现事务】 Andrei Alexandrescu & Petru Marginean 翻译:ye_feng 本文代码 编者按:这是 Generic系列中又一篇极好的文章。资源管理一直是程序设计中挥之不去的阴影,而其中最常见的就

lionzl的专栏 4359

异常安全,RAII与C++11 http://www.cnblogs.com/mavaL/articles/2515381.html

异常安全,RAII与C++11 C++11新标准支持lambda表达式后,异常安全的RAII解法就可以简洁高效了,见下面链接文章中的介绍(太好了,这样以后在我自己的代码中也能轻松支持上异常安全啦~)   http://blog.youkuaiyun.com/pongba/article/details/7911997   而在之前的C++98中,解法是大牛绞尽脑汁

诺尔曼 1015

ScopeGuard的使用

ScopeGuard的使用:Boost.ScopeExit、loki-lib.ScopeGuard

大草的博客 1355
上一篇: c++标准库总结
下一篇: 关于临时对象的引用
meteor1113
博客等级 码龄19年 16粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值