Managing resources

We have already seen one sort of resource that requires careful management: memory. You allocate memory with new, and when you have finished with the memory you must deallocate the memory with delete. A failure to deallocate the memory will cause a memory leak. Memory is, perhaps, the most fundamental of system resources, but most operating systems have many others: file handles, handles to graphic objects, synchronization objects, threads, and processes. Sometimes possession of such a resource is exclusive and will prevent other code from accessing the resource accessed through the resource. Thus, it is important that such resources are freed at some point, and, usually, that they are freed in a timely manner.

Classes help here with a mechanism called Resource Acquisition Is Initialization (RAII) invented by Bjarne Stroustrup, the author of C++. Put simply, the resource is allocated in the constructor of an object and freed in the destructor, so it means that the lifetime of the resource is the lifetime of the object. Typically, such wrapper objects are allocated on the stack, and this means that you are guaranteed that the resource will be freed when the object goes out of scope regardless of how this happens.

So, if objects are declared in the code block for a looping statement (while, for), then at the end of each loop the destructor for each will be called (in reverse order of creation) and the object will be created again when the loop is repeated. This occurs whether the loop is repeated because the end of the code block has been reached or if the loop is repeated through a call to continue. Another way to leave a code block is through a call to break, a goto, or if the code calls return to leave the function. If the code raises an exception (see Chapter 7, Diagnostics and Debugging), the destructor will be called as the object goes out of scope, so if the code is guarded by a try block, the destructor of objects declared in the block will be called before the catch clause is called. If there is no guard block, then the destructor will be called before the function stack is destroyed and the exception propagated.