R
Rolf Magnus
Daniel said:Hi all,
I just needed some kind of try...finally semantics in a method and was
wondering how to do this "the best way" -- there were two alternatives
which came to my mind:
1) RAII:
void A::method()
{
// Stuff here
// This is the "try...finally"
{
class Finally
{
private:
A& me;
public:
inline Finally(A& m)
: me(m)
{}
inline ~Finally()
{
me.foo=bar;
me.doSomething();
}
} finally(*this);
// Do the throwing stuff
}
// Stuff here
}
2) Catch and rethrow:
void A::method()
{
// Stuff here
#define DO_FINALLY \
foo=bar; \
doSomething();
try
{
// throwing stuff
} catch(...)
{
DO_FINALLY
throw;
}
DO_FINALLY
#undef DO_FINALLY
// Stuff here
}
Of course the RAII thing is "really" like try...finally, as for instance
an early return is caught, too, but the same is not true for 2); and 1)
seems much "cleaner" to me. However, there is some amount of bloat in
1) which seems to make the code a bit unreadable for me.
I believe most C++ programmers must have had a need for try...finally
functionality at some point, and I'd like to know how you solved it /
how you would recommend to solve it. Is there maybe some way I did not
think about?
Usually, if your classes are properly designed with a destructor that cleans
up, you get RAII implicitly and there is no need for 'finally'. Dynamically
allocated objects can be handled with std::auto_ptr if you don't already
use some type of shared pointer.