我有一个经常出现的问题,我找不到一个优雅的解决方案来避免资源清理代码重复:
resource allocation:
try {
f()
} catch (...) {
resource cleaning code;
throw;
}
resource cleaning code;
return rc;
Run Code Online (Sandbox Code Playgroud)
所以,我知道我可以用清理析构函数做一个临时类,但我不喜欢它,因为它打破了代码流,我需要给类引用所有堆栈变量进行清理,同样的问题与一个函数,我不知道如何不存在这个反复出现问题的优雅解决方案.
这个问题是RAII发明的原因.最佳实践是确保每个可释放资源都在对象内.或者,您可以使用Boost.ScopeExit或定义一个通用的sentinel类(在构造函数中接收仿函数并在析构函数中调用它的类)
编辑:在@Jackson指出的文章中,这被称为ScopeGuard.文中的实现可以通过与结合大大增强boost::function与boost::bind-或std::tr1::function和std::tr1::bind).
基本上不是文章中的整个架构,您的实现将如下所示:
class scoped_guard
{
boost::function<void(void)> atScopeExit;
public:
scoped_guard(const boost::function<void(void)>& func) : atScopeExit(func) {}
~scoped_guard() { try { atScopeExit(); } catch(...) {} }
};
Run Code Online (Sandbox Code Playgroud)
您可以通过添加解除它或其他东西的功能(在堆栈展开的情况下安全地捕获异常?)来进一步增强这一点吗?但是
我太懒了,不能把它留作读者的练习;).