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 member functions of the Pimpl class will (often) call the member functions 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].

 

 

 

 

 

Examples

 

 

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