Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Chapter 3.  Resource Encapsulation


3.6. RAII Coda

There's not much more to say about the fundamentals of the concept of RAII,[6] but there are myriad uses to which it can, and should, be put, some of which are examined in Chapter 6. There are two things I'd like to point out before we leave the subject.

[6] There's a lot more to be said about the details, though, such as sub-objects, member initialization, and exception-safety—all of which we'll get to in later parts of this book.

3.6.1 Invariants

The first pertains to class invariants (section 1.3), which feature throughout the book. Simply speaking, an invariant is a condition that must hold true for any instance of a class throughout its lifetime. In C++, the invariants are assessed either through dedicated member functions, or through individual testing, and may result in either an assertion or an exception being thrown.

An invariant should hold from the point at which a constructor is complete, until the point at which the destructor commences. The only times that the invariant may temporarily not hold is during state change in a member function. Hence assessments are done at the end of constructors, the beginning of the destructor, and at the start and end of any member functions, especially non-const ones.

The level of resource encapsulation impacts on the efficacy of invariants. If your class fully encapsulates its resources, instances can enforce invariants throughout their lifetimes. The degree to which your class breaks encapsulation corresponds to the degree to which invariants can be applied, which crudely corresponds to the level of confidence you can have in the correctness of your code. RAII classes can apply invariants throughout the lifetime of the instances. RRID classes can only really enforce invariants during the destruction of instances. POD types cannot have invariants, since they don't have access via methods, so there's nowhere to plug in the tests. Actually, this is not entirely fair. Insofar as POD types (open or opaque) are manipulated via API functions, the functions can (and should) test invariants, but it is an incomplete solution, nonetheless.

3.6.2 Error Handling

The last point to make regarding RRID and RAII is that they represent, to a degree, the debate between construction initialization and the dreaded "create function" (see section 6.3.1).

What can be said now is that internally initialized immutable RAII types are appropriate for use in exception-aware environments if the resource allocation can fail. Otherwise, we're in the realm of the nasty create and test idiom (section 6.3.1).


      Previous section   Next section