异常处理中的冗余代码

Nic*_*oni 1 c++

我有一个经常出现的问题,我找不到一个优雅的解决方案来避免资源清理代码重复:

resource allocation:

try {
  f()
} catch (...) {
  resource cleaning code;
  throw;
}

resource cleaning code;
return rc;
Run Code Online (Sandbox Code Playgroud)

所以,我知道我可以用清理析构函数做一个临时类,但我不喜欢它,因为它打破了代码流,我需要给类引用所有堆栈变量进行清理,同样的问题与一个函数,我不知道如何不存在这个反复出现问题的优雅解决方案.

utn*_*tim 8

这个问题是RAII发明的原因.最佳实践是确保每个可释放资源都在对象内.或者,您可以使用Boost.ScopeExit或定义一个通用的sentinel类(在构造函数中接收仿函数并在析构函数中调用它的类)

编辑:在@Jackson指出的文章中,这被称为ScopeGuard.文中的实现可以通过与结合大大增强boost::functionboost::bind-或std::tr1::functionstd::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)

您可以通过添加解除它或其他东西的功能(在堆栈展开的情况下安全地捕获异常?)来进一步增强这一点吗?但是 我太懒了,不能把它留作读者的练习;).