I'm familiar with the advantages of RAII, but I recently tripped over a problem in code like this:
class Foo
{
public:
Foo()
{
DoSomething();
...
}
~Foo()
{
UndoSomething();
}
}
All fine, except that code in the constructor ...
section threw an exception, with the result that UndoSomething()
never got called.
There are obvious ways of fixing that particular issue, like wrap ...
in a try/catch block that then calls UndoSomething()
, but a: that's duplicating code, and b: try/catch blocks are a code smell that I try and avoid by using RAII techniques. And, the code is likely to get worse and more error-prone if there are multiple Do/Undo pairs involved, and we have to clean up half-way through.
I'm wondering there's a better approach to doing this - maybe a separate object takes a function pointer, and invokes the function when it, in turn, is destructed?
class Bar
{
FuncPtr f;
Bar() : f(NULL)
{
}
~Bar()
{
if (f != NULL)
f();
}
}
I know that won't compile but it should show the principle. Foo then becomes...
class Foo
{
Bar b;
Foo()
{
DoSomething();
b.f = UndoSomething;
...
}
}
Note that foo now doesn't require a destructor. Does that sound like more trouble than it's worth, or is this already a common pattern with something useful in boost to handle the heavy lifting for me?
try {} catch(...) {throw;}
has rather a strong odour. – Hoiden