RAII
From Cppwiki
RAII (Resource Acquisition Is Initialisation) refers to a technique, often used in C++, to make dynamic resource management simpler and easier to do correctly. When using RAII for resource management, resources are acquired in object constructors and released in destructors. This is in contrast to traditional resource management which used explicit allocation and release functions.
A common example of RAII is used for lock management in multithreaded programs. Typical the platform's native threading API will provide a type (which we'll call lock_t) to represent the lock, and at least two functions, lock_acquire and lock_release. Typical use might look like this:
static int i;
lock_t i_lock;
void
incr_i(void)
{
lock_acquire(i_lock);
++i;
lock_release(i_lock);
}
In a trivial example like this, the lock handling is obviously correct: the lock is acquired and always released before the function returns. However, real-world programs often have several returns points from a function (e.g., for error checking), and more importantly, must deal with exceptions. For example:
static counter i; // some UDT implementing a counter
lock_t i_lock;
void
incr_i(void)
{
lock_acquire(i_lock);
if (!i.valid()) {
lock_release(i_lock);
return;
}
try {
i.incr();
} catch (...) {
lock_release(i_lock);
throw;
}
lock_release(i_lock);
}
This time, more of the function is taken up with error checking and exception handling than actually doing the job.
Instead of the lock_acquire/lock_release API, consider a C++ object, raii_lock. This function takes a lock_t as its ctor argument; on construction, it acquires the lock, and on destruction it releases the lock. (Such a class is trivial to implement; see below for an example). Using raii_lock, we can reimplement incr_i() thus:
static counter i;
lock_t i_lock;
void
incr_i(void)
{
raii_lock lock(i_lock);
if (i.valid())
i.incr();
}
Now the function is less than half the length, much clearer, and the programmer can clearly see that the lock management is correct.
Example raii_lock class
struct raii_lock {
raii_lock(lock_t const &lck_) : lck(lck_) {
lock_acquire(lck);
}
~raii_lock(void) {
lock_release(lck);
}
private:
raii_lock(raii_lock const &o); // noncopyable
lock_t const &lck;
};
Examples of RAII
- C++ fstreams: in contrast to fopen/fclose, destruction of the stream closes the file
- C++ containers: containers such as vector, map, etc. release their storage at destruction
- Pointer management (smart pointers):
- std::auto_ptr (limited RAII pointer)
- boost::smart_ptr, boost::scoped_ptr, etc.

