我经常遇到问题,我找不到一个优雅的解决方案来避免资源清理代码重复:
resource allocation:
try {
f()
} catch (...) {
resource cleaning code;
throw;
}
resource cleaning code;
return rc;
所以,我知道我可以做一个清理析构函数的临时类,但我不喜欢它,因为它打破了代码流,我需要给类引用所有堆栈变量进行清理,功能相同的问题,我不知道如何不存在这个反复出现问题的优雅解决方案。
答案 0 :(得分:8)
这个问题是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(...) {} }
};
您可以通过添加解除它或其他东西的功能(在堆栈展开的情况下安全地捕获异常?)来进一步增强这一点吗?但是
我懒得这是留给读者的练习;)。
答案 1 :(得分:3)
您可能想看一下boost :: scope_exit: http://www.boost.org/doc/libs/1_39_0/libs/scope_exit/doc/html/index.html
答案 2 :(得分:2)
这篇Dr Dobbs文章可能会有所帮助。
答案 3 :(得分:0)
你需要自我释放的资源,这真的不难做到。
对于内存使用autopointers,STL,Boost或自己制作,这并不难。
对于文件,最好使用std :: fstream。如果你必须使用fopen或CreateFile(或其他)创建一个简单的句柄类,在破坏时调用适当的close函数。
与任何其他资源类似,构建一组智能句柄类。