我熟悉RAII的优点,但我最近绊倒了一个问题,像这样的代码:如何处理构造失败的RAII
class Foo
{
public:
Foo()
{
DoSomething();
...
}
~Foo()
{
UndoSomething();
}
}
一切都很好,除了在构造...
节代码抛出异常,结果UndoSomething()
从未被调用过。
有固定的特定问题,就像在一个try/catch块,然后调用UndoSomething()
包装...
的明显的方式,而是:这是复制代码,和b:try/catch块是一个代码味道,我尝试避免使用RAII技术。而且,如果涉及多个Do/Undo对,代码可能会变得更糟且更容易出错,并且我们必须清理一半。
我想知道有一个更好的方法来做到这一点 - 也许一个单独的对象需要一个函数指针,并且当它反过来被破坏时调用该函数?
class Bar
{
FuncPtr f;
Bar() : f(NULL)
{
}
~Bar()
{
if (f != NULL)
f();
}
}
我知道不会编译,但它应该显示原理。 Foo然后变成...
class Foo
{
Bar b;
Foo()
{
DoSomething();
b.f = UndoSomething;
...
}
}
请注意,foo现在不需要析构函数。这听起来像是比它的价值更麻烦,还是这已经是一种常见的模式,有助于处理我的繁重工作?
try/catch是_not_代码味道,并经常被使用IMO。 – 2012-07-05 14:20:44
看这里:http://www.parashift.com/c++-faq-lite/selfcleaning-members.html – MadScientist 2012-07-05 14:22:11
@MooingDuck:的确,他们本身并没有味道。但是'try {} catch(...){throw;}'有相当强烈的气味。 – 2012-07-05 14:56:49