C++11的资源管理:泛化的RAII
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的更多相关文章
- 使用C++11新特性来实现RAII进行资源管理
方法一:借助auto.decltype.unique_ptr.Lambda表达式构造 sqlite3 *db = NULL; auto deleter = [](sqlite3 *pdb){sqlit ...
- RAII惯用法:C++资源管理的利器(转)
RAII惯用法:C++资源管理的利器 RAII是指C++语言中的一个惯用法(idiom),它是“Resource Acquisition Is Initialization”的首字母缩写.中文可将其翻 ...
- C++ —— 笔记汇总
导读 本文仅用于记录在个人在使用C++过程中的遇到一些的疑问和概念. 目录 语法和概念基础 常用函数 编程注意 编译问题 拓展链接 1.语法和概念基础 1.块域 2.static 作用域 ...
- c语言函数的嵌套使用和矩阵运算
这段时间,听刚刚学习c的同学说函数嵌套运用不太熟练,想做一个简单的程序进行练习,我也就当练练手了,哈哈.虽然说是比较简单,但是其中的思维也是值得思考的. 一.函数的嵌套使用 简单说明题目:对于等式 y ...
- oracle dba 职责, 及个人需要掌握内容
ORACLE DBA 职责, 基本相当于日常工作. 0. 数据库设计 1. 模式对象的创建与管理(table, index 等等) 2. 事物管理, 例如并发等 3. SQL 调优 只是针对SQL的 ...
- [译]C++书籍终极推荐
转载声明: 翻译仅以技术学习和交流为目的,如需转载请务必标明原帖链接. 来源:http://stackoverflow.com/questions/388242/the-definitive-c-bo ...
- 16Aspx.com源码2013年10月到2013年12月详细
创建时间FROM: 创建时间TO: ExtJS合同管理信息系统源码 2013-12-13 [VS2008] 源码介绍: ExtJS合同管理信息系统源码浏览器兼容:IE,Firefox,谷歌等主 ...
- 黑马程序员 ——Java SE(1)
----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...
- ASP.NET通用权限框架 权限管理系统源码jquery 精美UI源码
软件技术开发,合作请联系QQ:858-048-581 开发工具 VS2010 .sql2005.2008等(在Sql server数据执行脚本即可) VS2010 打开保证本地运行成功(数据库.源代 ...
随机推荐
- CSS定位机制
CSS中,存在3种定位机制:标准文档流(Normal flow) * 特点:从上到下,从左导游,输出文档内容 * 由块级元素和行级元素组成 浮动(Floats) * 能够实现横向多列布局 * 设置了浮 ...
- Google Web Designer 测试
这东东完全就是一个flash啊,简单测试,感觉就是个做HTML5动画的..不过暂时是beta版的, 官方安装版的半天打不开,这边有个绿色版的,需要的童鞋可以这里下载:百度网盘
- less学习-语法(二)
变量 @color1:#fff; 选择器 // Variables @mySelector: banner; // Usage .@{mySelector} { font-weight: bold; ...
- grunt-npm编译bootstrap源码
因为gmu需要用编译的方式下载,于是联想到bootstrap什么less sass编译 less先学,据说基于js编译和less编译器,安装起来详细, sass据网上介绍基于ruby, 以下为在mac ...
- PHP小记录
正的framework(大量使用) thinkphp(部分使用) cakephpyii(极少使用) [一]函数 1:函数的声明:每个函数的第一行都是函数开头,有声明函数的关键 ...
- 使用XmlDocument.SelectNodes遍历xml元素遇到的一个XPathException
使用XmlDocument类时候报错: 未处理的XPathException:需要命名空间管理器或 XsltContext.此查询具有前缀.变量或用户定义的函数. 需要使用XmlNamespaceMa ...
- 把 Eclipse 中的工程 Push 到 Github(适用 Windows 平台)
今天发现一小技巧,关于如何把Eclipse的某一个Existing project push 到github服务器. Eclipse 应该是 JavaEE 版本. 在project 右键 team, ...
- Java 8 的 JVM 有多快?Fork-Join 性能基准测试
Java 8 已经发布一段时间了,许多开发者已经开始使用 Java 8.本文也将讨论最新发布在 JDK 中的并发功能更新.事实上,JDK 中已经有多处java.util.concurrent 改动,但 ...
- C盘瘦身,可以让你的电脑C盘恢复到刚安装时的大小
@echo offecho 正在清理系统垃圾文件,请稍等......del /f /s /q %systemdrive%\*.tmpdel /f /s /q %systemdrive%\*._mpde ...
- 只看Delphi自带的WnAPI帮助似乎不够
比如,MessageBox在Delphi自带帮助的参数说明中,对其第四个参数的MB_类型说明只有最常见的6种类型,这么多年搞得我天经地义的以为MessageBox就是这么简单.今天看了一位前辈写的老代 ...