我熟悉 RAII 的优点,但我最近在这样的代码中遇到了一个问题:
class Foo
{
public:
Foo()
{
DoSomething();
...
}
~Foo()
{
UndoSomething();
}
}
一切都很好,除了构造函数...
部分中的代码引发了异常,结果UndoSomething()
从未被调用。
有一些明显的方法可以解决这个特定的问题,比如包装...
在一个 try/catch 块中,然后调用UndoSomething()
,但是 a: 那是重复的代码,而 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 现在不需要析构函数。这听起来比它的价值更麻烦,还是这已经是一种常见的模式,有一些有用的东西可以帮助我处理繁重的工作?