Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Pimpl

 

Pimpl is an abbreviation of 'pointer to implementation'.

 

The idea of the Pimpl idiom is to give a class (for example 'Lizard') an opaque (smart) pointer to the actual implementation (for example 'LizardImpl'). The opaque (smart) pointer enables it to do a forward declaration of the implementation class only, without the compiler needing to know the actual type. This shortens build times [1]. All the public methods of the Pimpl class will (often) call the methods of the implementation class with the same name.

 

The advantages of using the Pimpl idiom are:

 

The disadvantage of using the Pimpl idiom is the cost of an extra level of indirection, so Pimpl judiciously [1].

 

 

 

 

 

Example

 

Most lizards remain having the same gender for all their live. Therefore, it is a good idea to make a lizard's gender a const member variable. Problem is, that this makes a lizard class uncopyable. In this example I solve this by making a Lizard contain an opaque pointer to LizardImpl, where a LizardImpl does have a constant gender. Because I want to be able to do a shallow copy on Lizards, I use a boost::shared_ptr. Also note that the code is very similar to a Strategy design pattern.

 

 

 

 

 

 

lizard.h

 

//---------------------------------------------------------------------------
// UnitLizard.h
//---------------------------------------------------------------------------
#ifndef UnitLizardH
#define UnitLizardH
//---------------------------------------------------------------------------
#include <boost/shared_ptr.hpp>
//---------------------------------------------------------------------------
enum Gender { male, female };

struct Lizard
{
  Lizard(const Gender gender);
  const Gender GetGender() const;
  private:
  struct LizardImpl;
  boost::shared_ptr<LizardImpl> mPimpl;
};
#endif

 

 

 

 

 

lizard.cpp

 

//---------------------------------------------------------------------------
// UnitLizard.cpp
//---------------------------------------------------------------------------
#include "UnitLizard.h"
//---------------------------------------------------------------------------
struct Lizard::LizardImpl
{
  LizardImpl(const Gender gender);
  const Gender mGender;
};
//---------------------------------------------------------------------------
Lizard::Lizard(const Gender gender)
  : mPimpl(boost::shared_ptr<LizardImpl>(new LizardImpl(gender) ) )
{

}
//---------------------------------------------------------------------------
const Gender Lizard::GetGender() const
{
  return mPimpl->mGender;
}
//---------------------------------------------------------------------------
// The actual Lizard implementation
//---------------------------------------------------------------------------
Lizard::LizardImpl::LizardImpl(const Gender gender) : mGender(gender)
{

}
//---------------------------------------------------------------------------

 

 

 

 

 

References

 

  1. Herb Sutter, Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Item 43: 'Pimpl judiciously'.

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml