(原创)用c++11实现简洁的ScopeGuard
ScopeGuard的作用是确保资源面对异常时总能被成功释放,就算没有正常返回。惯用法让我们在构造函数里获取资源,当因为异常或者正常作用域结束,那么在析构函数里释放资源。总是能释放资源。如果没有异常抛出则正常结束,只是有异常发生或者没有正常退出时释放资源。关于ScopeGaurd的概念想多了解一点的童鞋点这里和这里。c#中的ScopeGuard比较简单,通过using初始化或者通过finally就可以做到,c++中需要自己去实现。
c++中设计ScopeGuard的关键技术:通过局部变量析构函数来管理资源,根据是否是正常退出来确定是否需要清理资源。用c++11做很简单。
template <typename F>
class ScopeGuard
{
public:
explicit ScopeGuard( F && f) : m_func(std::move(f)), m_dismiss(false){}
explicit ScopeGuard(const F& f) : m_func(f), m_dismiss(false){} ~ScopeGuard()
{
if (!m_dismiss)
m_func();
} ScopeGuard(ScopeGuard && rhs) : m_func(std::move(rhs.m_func)), m_dismiss(rhs.m_dismiss){rhs.Dismiss();} void Dismiss()
{
m_dismiss = true;
} private:
F m_func;
bool m_dismiss; ScopeGuard();
ScopeGuard(const ScopeGuard&);
ScopeGuard& operator=(const ScopeGuard&);
//template<class... Args>
//auto Run(Args&&... args)->typename std::result_of<F(Args...)>::type
//{
// return m_func(std::forward<Args>(args)...);
//}
};
template <typename F>
ScopeGuard<typename std::decay<F>::type> MakeGuard(F && f)
{
return ScopeGuard<typename std::decay<F>::type>(std::forward<F>(f));
}
测试代码:
void TestScopeGuard()
{
std::function < void()> f = [] { cout << "cleanup from unnormal exit" << endl; };
//正常退出
{
auto gd = MakeGuard(f);
//...
gd.Dismiss();
} //异常退出
{
auto gd = MakeGuard(f);
//...
throw ;
} //非正常退出
{
auto gd = MakeGuard(f);
return;
//...
}
}
通过测试程序可以知道,当程序没有发生异常正常退出时,需要调用一下Dismiss函数,以解除ScopeGuard,当程序异常退出时,会进入异常处理函数去释放相应资源,实现ScopeGuard的目的。
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
(原创)用c++11实现简洁的ScopeGuard的更多相关文章
- (原创)C++11改进我们的程序之简化我们的程序(八)
本次要讲的是如何通过泛型函数来简化我们的程序. 泛型函数除了之前介绍的一些优点外还有两个重要的优点 1.消除重复逻辑,提高程序的内聚性和健壮性 泛型函数在某种程度上用来弥补泛型类型的不足.通过泛型类型 ...
- (原创)C++11改进我们的程序之简化我们的程序(七)
这次要讲的内容是:c++11中的tuple(元组).tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多 ...
- (原创)C++11改进我们的程序之简化我们的程序(六)
这次要讲的内容是:c++11中的lamda表达式. lamda表达式是我最喜欢的一个c++11特性之一,在我的代码中随处可见它的身影,其实在c#3.5中就引入了lamda,java中至今还没引入,要等 ...
- (原创)C++11改进我们的程序之简化我们的程序(四)
这次要讲的是:c++11统一初始化.统一begin()/end()和for-loop循环如何简化我们的程序 初始化列表 c++11之前有各种各样的初始化语法,有时候初始化的时候还挺麻烦,比较典型的如v ...
- (原创)C++11改进我们的程序之简化我们的程序(二)
这次要讲的是:C++11如何通过组合函数来简化我们的程序.关于组合函数,大家可能对这个概念有点陌生.组合函数是将N个一元函数组成一种更复杂的函数,每个函数的返回值作为参数传给下一个函数,直到传到最后一 ...
- (原创)C++11改进我们的程序之简化我们的程序(一)
C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返回值类型来简化我们的程序.在谈到简化之前,我们先 ...
- (原创)c++11改进我们的模式之改进单例模式
我会写关于c++11的一个系列的文章,会讲到如何使用c++11改进我们的程序,本次讲如何改进我们的模式,会讲到如何改进单例模式.观察者模式.访问者模式.工厂模式.命令模式等模式.通过c++11的改进, ...
- 【原创】C++11:左值和右值(深度分析)
——原创,引用请附带博客地址 2019-12-06 23:42:18 这篇文章分析的还是不行,先暂时放在这以后再更新. 本篇比较长,需要耐心阅读 以一个实际问题开始分析 class Sub{} Sub ...
- 原创:goldengate从11.2升级到12.1.2
goldengate从11.2升级到12.1.2 1.停止抽取进程 GGSCI (001.oracle.drs.dc.com) 286> stop EXTSJ01 2. 停止投递和复制进程 等待 ...
随机推荐
- 基于kettle8的web端调度监控平台
发布时间:2018-11-16 技术:spring+springmvc +beetlsql+quartz+kettle8 概述 Kettle调度监控平台(以下简称KS)是一个自主开发的java ...
- 微信小程序解决方案合集
微信小程序解决方案合集:http://www.wxapp-union.com/special/solution.html 跳坑系列:http://www.wxapp-union.com/forum.p ...
- Xcode 常用调试技巧总结
NSLog,po命令和普通断点调试相信每个iOS开发者都会,这里就不作介绍了. 一.Memory Graph Xcode8新增:Memory Graph解决闭包引用循环问题 有很多叹号说明就有问题了. ...
- 超酷的 Vim 搜索技巧
尽管目前我们已经涉及 Vim 的多种特性,但此编辑器的特性集如此庞大,不管我们学习多少,似乎仍然远远不足.承接我们的 Vim 教程系列,本文我们将讨论 Vim 提供的多种搜索技术. 不过在此之前,请注 ...
- 进阶之路(基础篇) - 005 模拟PWM波控制引脚
/********************************* 代码功能:输出PWM波控制引脚 使用函数: 创作时间:2016*10*07 作者邮箱:jikexianfeng@outlook.c ...
- CocoaPods iOS 开源库管理
1.CocoaPods 简介 1.1 CocoaPods CocoaPods 是 macOS 和 iOS 下的一个第三类库管理工具,通过 CocoaPods 工具我们可以为项目添加被称为 " ...
- pingback协议与traceback协议的区别
wordpress 的 pingback协议与traceback协议区别
- git server 搭建指南
搭建git服务器的经验总结 一: Server端的设置 1. 安装 git, git-core 2. 安装 ssh-server. (代码上传通道) 3. 创建git 用户 指定其目录 和所在组 4. ...
- Unix网络编程 之 基本套接字调用(一)
Unix/Linux支持伯克利风格的套接字编程,它同一时候支持面向连接和面向无连接类型的套接字. 套接字最经常使用的一些系统调用: socket() bind() connect() listen() ...
- 设计模式C++实现——模板方法模式
模式定义: 模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类能够在不改变算法结构的情况下,又一次定义算法中的某些步骤. 模板就是一个方法.更详细的说.这种方法将 ...