I've a recurrent problem, I don't find an elegant solution to avoid the resource cleaning code duplication:
resource allocation:
try {
f()
} catch (...) {
resource cleaning code;
throw;
}
resource cleaning code;
return rc;
So, I know I can do a temporary class with cleaning up destructor, but I don't really like it because it breaks the code flow and I need to give the class the reference to the all stack vars to cleanup, the same problem with a function, and I don't figure out how does not exists an elegant solution to this recurring proble开发者_Go百科m.
This problem is why RAII was invented. The best practice is to make sure that every releasable resource is inside an object. Alternately, you can use Boost.ScopeExit or define a generic sentinel class (a class that receives a functor in constructor and calls it in the destructor)
Edit: In the article pointed out by @Jackson, this is called ScopeGuard
. The implementation in the article could greatly enhanced by combining it with boost::function
and boost::bind
- or std::tr1::function
and std::tr1::bind
).
Basically instead of the whole architecture in the article, your implementation would look like this:
class scoped_guard
{
boost::function<void(void)> atScopeExit;
public:
scoped_guard(const boost::function<void(void)>& func) : atScopeExit(func) {}
~scoped_guard() { try { atScopeExit(); } catch(...) {} }
};
You can further enhance this by adding the capability to dismiss it or other things (capturing exceptions safely in case of stack unwinding?) but
I'm too lazy to that's left as an exercise to the reader ;).
You might want to have a look at boost::scope_exit: http://www.boost.org/doc/libs/1_39_0/libs/scope_exit/doc/html/index.html
This Dr Dobbs article might help.
You need self-releasing resources, which is really not hard to do.
For memory use autopointers, STL, Boost or make your own, it isn't hard.
For files, preferably use an std::fstream. If you must use fopen or CreateFile (or whatever) make a simple handle class that calls the appropriate close function on destruction.
Similarly for any other resources, build a collection of smart handle classes.
精彩评论