RAII被认为是c++资源管理的最佳范式,但是c++98中用RAII必须为要管理的资源写一个类,这样一来RAII的使用就有些繁琐了。C++11有了lambda和function后,我们就可以编写泛化的RAII,实现ScopeGuard,优雅地解决这个问题。本文主要参考刘未鹏的博客

主要代码如下

class ScopeGuard
{
public:
explicit ScopeGuard(std::function<void()> onExitScope)
: onExitScope_(onExitScope), dismissed_(false)
{ } ~ScopeGuard()
{
if (!dismissed_)
{
onExitScope_();
}
} void Dismiss()
{
dismissed_ = true;
} private:
std::function<void()> onExitScope_;
bool dismissed_; private: // noncopyable
ScopeGuard(ScopeGuard const&);
ScopeGuard& operator=(ScopeGuard const&);
};

为了在管理多个资源时不用花精力想变量名,可以定义几个宏

#define SCOPEGUARD_LINENAME_CAT(name, line) name##line
#define SCOPEGUARD_LINENAME(name, line) SCOPEGUARD_LINENAME_CAT(name, line)
#define ON_SCOPE_EXIT(callback) ScopeGuard SCOPEGUARD_LINENAME(EXIT, __LINE__)(callback)

其中##是连接符,__LINE__是编译器自带的宏,指的是源代码的行号。这样就会自动生成变量名为"EXIT行号"。

应用如下

class A {
public:
int a;
A(int i) :a(i) {}
}; void EraseA(A &a)
{
a.a = ;
cout << "eraseA" << endl;
} int main()
{
A a();
ON_SCOPE_EXIT([&] { EraseA(a); });
return ;
}

程序结束时输出eraseA。

Dismiss()函数作用是为了支持rollback模式,例如:

ScopeGuard onFailureRollback([&] { /* rollback */ });
... // do something that could fail
onFailureRollback.Dismiss();

如果“do something”的代码出错,就执行析构函数中的rollback逻辑。如果代码顺利运行,就将dismissed_设为true,这样在退出作用域时就不会执行rollback操作了。

lambda表达式用于创建匿名函数对象语法格式如下

[捕获列表] (函数参数) mutable或exception声明 ->返回类型 {函数体};

捕获列表是一个lambda所在函数中定义的局部变量的列表,可以为空,上文的[&]表示默认使用引用传值,如果用[=]则表示默认使用值传递。

最简单的使用方法如下

auto f = [] {return ;};
cout<<f()<<endl;

结果打印42。

C++11的资源管理:泛化的RAII的更多相关文章

  1. 使用C++11新特性来实现RAII进行资源管理

    方法一:借助auto.decltype.unique_ptr.Lambda表达式构造 sqlite3 *db = NULL; auto deleter = [](sqlite3 *pdb){sqlit ...

  2. RAII惯用法:C++资源管理的利器(转)

    RAII惯用法:C++资源管理的利器 RAII是指C++语言中的一个惯用法(idiom),它是“Resource Acquisition Is Initialization”的首字母缩写.中文可将其翻 ...

  3. C++ —— 笔记汇总

    导读 本文仅用于记录在个人在使用C++过程中的遇到一些的疑问和概念. 目录 语法和概念基础 常用函数 编程注意 编译问题 拓展链接 1.语法和概念基础 1.块域     2.static 作用域    ...

  4. c语言函数的嵌套使用和矩阵运算

    这段时间,听刚刚学习c的同学说函数嵌套运用不太熟练,想做一个简单的程序进行练习,我也就当练练手了,哈哈.虽然说是比较简单,但是其中的思维也是值得思考的. 一.函数的嵌套使用 简单说明题目:对于等式 y ...

  5. oracle dba 职责, 及个人需要掌握内容

    ORACLE DBA 职责, 基本相当于日常工作. 0. 数据库设计 1. 模式对象的创建与管理(table, index 等等) 2. 事物管理, 例如并发等 3. SQL 调优 只是针对SQL的 ...

  6. [译]C++书籍终极推荐

    转载声明: 翻译仅以技术学习和交流为目的,如需转载请务必标明原帖链接. 来源:http://stackoverflow.com/questions/388242/the-definitive-c-bo ...

  7. 16Aspx.com源码2013年10月到2013年12月详细

    创建时间FROM: 创建时间TO:   ExtJS合同管理信息系统源码 2013-12-13   [VS2008] 源码介绍: ExtJS合同管理信息系统源码浏览器兼容:IE,Firefox,谷歌等主 ...

  8. 黑马程序员 ——Java SE(1)

    ----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...

  9. ASP.NET通用权限框架 权限管理系统源码jquery 精美UI源码

    软件技术开发,合作请联系QQ:858-048-581 开发工具 VS2010 .sql2005.2008等(在Sql server数据执行脚本即可)  VS2010 打开保证本地运行成功(数据库.源代 ...

随机推荐

  1. CentOS6.5下docker的安装及遇到的问题和简单使用

    Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS.Go语言.cgroup实现了资源的独立,可以很轻松的实现文件.资 ...

  2. PHPUML 生成UML

    Selecting the UML/XMI version To select which version of the UML/XMI standards you want your XMI to ...

  3. 《sort帮你排序》-linux命令五分钟系列之二十六

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  4. Expat Parser解析xml文件

    Expat 解析器是基于事件的解析器. 基于事件的解析器集中在 XML 文档的内容,而不是它们的结构.正因为如此,基于事件的解析器能够比基于树的解析器更快地访问数据. 请看下面的 XML 片段: &l ...

  5. sitecustomize.py 用法

    1.在python安装目录下的lib下的site-packages 目录中,新建文件sitecustomize.py.这是个特殊的文件,在python启动时会自动执行其中的语句.在sitecustom ...

  6. MVC页面上多个提交按钮提交到不同的Action

    使用mvc扩展类,ActionNameAttribute方法如下: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, In ...

  7. iOS -一些常用的方法

    1.获取本地的语言 + (NSString *)getLocalLanguage { NSString *language = [[[NSUserDefaults standardUserDefaul ...

  8. IOS中获取文件路径的方法

    iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory ...

  9. HTML5之本地文件系统API - File System API

    HTML5之本地文件系统API - File System API 新的HTML5标准给我们带来了大量的新特性和惊喜,例如,画图的画布Canvas,多媒体的audio和video等等.除了上面我们提到 ...

  10. 关于ARP欺骗与MITM(中间人攻击)的一些笔记( 二 )

    一直没有折腾啥东西,直到最近kali Linux发布,才回想起应该更新博客了….. 再次说明,这些技术并不是本人原创的,而是以前记录在Evernote的旧内容(排版不是很好,请谅解),本文是继关于AR ...