From: Asger Mangaard (tmb_at_[hidden])
Date: 2005-10-07 09:28:26


> Richard wrote:
>
> According to "Exceptional C++" there are four common pimpl implementation
> types:
> " 1. All private data (but not functions) go in the impl
> 2. Put all private members into impl
> 3. Put all private and protected members into impl
> 4. Make pimpl entirely the class that impl would have been, and write
> pimpl as only the public interface made up entirely of simple forwarding
> functions (a handle/body variant)"
>
> (It states that number 3 is "wrong".)
>
> In variants 1 and 2 pimpl has the public and protected methods in it and
> their implementation. In variant 4 pimpl has forwarding functions. How
> do I add member functions and their implementation to your pimpl class?

What is discussed in exceptional C++ is the use of the pimpl idiom. The
library does not implement any of these types, you do. The library just
eases the underlying work with memory management, etc.

Eg. A gameplayer class.

Type 1:
---------

.hpp:
struct GamePlayer
{

  void IncreaseLives();
  void MoveTo( Vector3 _newPosition);

private:
  boost::pimpl<struct GamePlayerValues> m_Values;
};

.cpp

struct GamePlayerValues
{
  CMyIntegerType m_Lives;
  Vector3 m_Position;
};

void GamePlayer::IncreaseLives()
{
  m_Values->m_Lives ++;
}

void GamePlayer::MoveTo( Vector3 _newPosition)
{
  m_Values->m_Position = _newPosition;
}

etc.

In the gameplayer class we hide all our 'private' values. So when someone
includes the hpp file they don't see that our 'lives' are stored in a
special integer class, CMyIntegerType. This has several advantages:

* When 'CMyIntegerType' changes only the cpp file needs recompiling thus
potentially reducing compile times greatly.

* You completely hide the content of 'GamePlayerValues' from all other
than the cpp file. In case it's secret :)

Also, I guess type 3 is 'wrong' because protected values should be visible
to derived classes, and with the pimpl idiom you hide those values like
explained above.

Regards,
Asger Mangaard