In C++, local instances (these not allocated by hand) have their destructors run as soon as they go out of scope. This behavior is explored in a few different schemes, besides its obvious intent of destructing the instance. The most known one is the auto_ptr class, part of the STL. It is merely a memory guard which takes care of deallocating the given pointer once its own scope is over. In the short example below, the s variable won’t leak.
#include <stdlib.h> #include <memory> #include <iostream> using namespace std; void f() { char *s = strdup("foobar"); auto_ptr<char> sp(s); cout << sp.get() << endl; }
While this is an interesting place to use this concept, it’s a good algorithm to be aware of generically. A good example of how useful this could be is how the apt-shell (part of APT-RPM) cache guard mechanism was implemented. This program was implemented as a refactoring of apt-get, but they have a fundamental difference: while apt-get is a one-shot program (run just once, and get back to the user), apt-shell maintains the internal cache (the structure where information about the packages is kept) alive for a long time, and changes it in many different ways during its execution time. Thus, I had to implement some way to make it easy to protect this cache against being unadvisedly changed in all these functions coming from apt-get. To do that, I have implemented an AutoRestore class which takes care of restoring the original state of the cache, unless explicitly told to release it. Here is the complete class, from apt-shell.cc:
class AutoRestore { pkgDepCache::State State; bool Guarded; public: inline pkgDepCache::State *operator ->() {return &State;}; inline pkgDepCache::State *operator &() {return &State;}; inline void UnGuard() { Guarded = false; }; AutoRestore(pkgDepCache &Cache) : State(&Cache), Guarded(true) {}; ~AutoRestore() { if (Guarded) State.Restore(); }; };
To use it, it’s just a matter of creating a local instance, passing the cache to the constructor. It will take care of undoing unexpected changes. Really comfortable!