Friday, September 16, 2005

Using the pImpl idiom with an auto_ptr

Here's a interesting C++ fact I had never figured out. The pImpl idiom is a method of hiding implementation details of a class from users of the class. You define the class's interface in its .h file, and then add a simple forward-declaration:

class myClassImpl;

and in the class, include a member variable:

myClassImpl* pImpl;

(pImpl stands for Pointer to Implementation.)

Then, in the class's CPP file, the constructor news up pImpl and the destructor deletes it, and the declaration of class myClassImpl can be pushed off to a different file or even hidden entirely in the class CPP file.

But still, there's a step in there we might be able to get rid of. The standard class auto_ptr defines a pointer that will be deleted when it goes out of scope. So, instead of using a raw pImpl pointer in the class definition, we define it like this:

std::auto_ptr pImpl;

Now the auto_ptr goes out of scope when the instance is destroyed, so we don't even need to delete it in the destructor. But wait - there's a problem. If we happen to have a class destructor that's defined in the header file, it won't be able to delete pImpl because, at that point, it doesn't have a definition for it. This seems like a minor issue, until you realize that, if you don't define a destructor at all, that works exactly the same as if you had defined it in the header file. So, as Gene Bushuyev explains in the referenced article, you need to define a destructor explicitly as well, so the compiler has enough information to delete pImpl when it needs to. Thanks, Gene!


Icerocket tags: