(原创)用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 1; } //非正常退出 { auto gd = MakeGuard(f); return; //... } }
通过测试程序可以知道,当程序没有发生异常正常退出时,需要调用一下Dismiss函数,以解除ScopeGuard,当程序异常退出时,会进入异常处理函数去释放相应资源,实现ScopeGuard的目的。
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
posted on 2013-11-13 14:20 qicosmos(江南) 阅读(5682) 评论(7) 编辑 收藏 举报