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的更多相关文章

  1. (原创)C++11改进我们的程序之简化我们的程序(八)

    本次要讲的是如何通过泛型函数来简化我们的程序. 泛型函数除了之前介绍的一些优点外还有两个重要的优点 1.消除重复逻辑,提高程序的内聚性和健壮性 泛型函数在某种程度上用来弥补泛型类型的不足.通过泛型类型 ...

  2. (原创)C++11改进我们的程序之简化我们的程序(七)

    这次要讲的内容是:c++11中的tuple(元组).tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多 ...

  3. (原创)C++11改进我们的程序之简化我们的程序(六)

    这次要讲的内容是:c++11中的lamda表达式. lamda表达式是我最喜欢的一个c++11特性之一,在我的代码中随处可见它的身影,其实在c#3.5中就引入了lamda,java中至今还没引入,要等 ...

  4. (原创)C++11改进我们的程序之简化我们的程序(四)

    这次要讲的是:c++11统一初始化.统一begin()/end()和for-loop循环如何简化我们的程序 初始化列表 c++11之前有各种各样的初始化语法,有时候初始化的时候还挺麻烦,比较典型的如v ...

  5. (原创)C++11改进我们的程序之简化我们的程序(二)

    这次要讲的是:C++11如何通过组合函数来简化我们的程序.关于组合函数,大家可能对这个概念有点陌生.组合函数是将N个一元函数组成一种更复杂的函数,每个函数的返回值作为参数传给下一个函数,直到传到最后一 ...

  6. (原创)C++11改进我们的程序之简化我们的程序(一)

    C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返回值类型来简化我们的程序.在谈到简化之前,我们先 ...

  7. (原创)c++11改进我们的模式之改进单例模式

    我会写关于c++11的一个系列的文章,会讲到如何使用c++11改进我们的程序,本次讲如何改进我们的模式,会讲到如何改进单例模式.观察者模式.访问者模式.工厂模式.命令模式等模式.通过c++11的改进, ...

  8. 【原创】C++11:左值和右值(深度分析)

    ——原创,引用请附带博客地址 2019-12-06 23:42:18 这篇文章分析的还是不行,先暂时放在这以后再更新. 本篇比较长,需要耐心阅读 以一个实际问题开始分析 class Sub{} Sub ...

  9. 原创:goldengate从11.2升级到12.1.2

    goldengate从11.2升级到12.1.2 1.停止抽取进程 GGSCI (001.oracle.drs.dc.com) 286> stop EXTSJ01 2. 停止投递和复制进程 等待 ...

随机推荐

  1. (转)Delta3D源码分析

    最近学习Delta3D,  2.4版忙着发布,一直不能成功编译SimCore, 索性静下心来看看源码,官网上竟然提供了几个重要组建的软件设计说明书(SDD),虽说基本都是2005版了,不过我看了后觉得 ...

  2. OpenCV 数字验证码识别

    更新后代码下载链接在此! !! 点我下载 本文针对OpenCv入门人士.由于我也不是专门做图像的,仅仅是为了完毕一次模式识别的小作业. 主要完毕的功能就是自己主动识别图片中的数字.图片包含正常图片,有 ...

  3. 纯C++去雾算法

    去雾算法 前言:经过不断的改进研究,该算法最终稳定,高效的问世了. 经过研究使该算法适应大雾环境,对该算法的内存优化,可以实时的高效的执行. 一.实时视频: watermark/2/text/aHR0 ...

  4. 通过Intent传递对象

    BluetoothDevice device = data.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 在蓝牙开发中,通过intent(data ...

  5. EntityFramework 5.0 CodeFirst 教程02-删除和修改/架构改变异常的处理

    -----------------------------------------------------目录--------------------------------------------- ...

  6. linux获取精准进程PID之pgrep命令

    pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行.在服务器的配置和管理中,这个工具常被应用,简单明了. 用法: #pgrep [选项] [程序名] pgrep [-flvx ...

  7. (原)SphereFace及其pytorch代码

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/8524937.html 论文: SphereFace: Deep Hypersphere Embeddi ...

  8. [转载]将archlinux&nbsp;2013-06-01版,安装配置为个人工作站

    原文地址:将archlinux 2013-06-01版,安装配置为个人工作站作者:老圃无蔓 安装所使用的镜像为:archlinux-2013.06.01-dual.iso.首先请看看我安装完成之后的效 ...

  9. jquery ajax 回调函数的值alert出来[object Object] 解决方法

    $("#activity_project").change(function(){ var pro=$("#activity_project").val(); ...

  10. Linux软中断、tasklet和工作队列

    Linux内核中的软中断.tasklet和工作队列详解 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来 ...