The PIMPL idiom

In C++ when anything in a header file changes, all code that includes the header (either directly or indirectly) must be recompiled. To minimalize this we use PIMPL idiom:


// file x.h
class X
{
public:
    // public members
protected:
    // protected members
private:
    // pointer to forward declared class
    class XImpl *pimpl_;  // opaque pointer
};

Questions: -- What should go into XImpl? Options are:

-- Does XImpl require a pointer back to the X object?

Caveats:

PIPML has some drawbacks, like allocating/deallocating objects in the heap, which could be slow.

What about this "optimalization"?


// file: y.h

class Y
{
    //...
    static const size_t sizeofx = /* ... */;
    char x_[sizeofx];
};


// file: y.cpp

#include "x.h"

Y::Y()
{
    assert( sizeofx >= sizeof(X) );
    new(&x_[0]) X;
}

Y::~Y()
{
    (reinterpret_cast<X*>(&x_[0]))->~X();
}

Questions:

Space overhead:


#include <iostream>

using namespace std;

struct X {
    char c;
    struct XImpl *pimpl_;
};
struct XImpl { char c; };

int main()
{
    cout << sizeof(XImpl) << '\t' << sizeof(X) << endl;
    return 0;
}

// result: 1    8

Runtime overhead:


// file x.h

class X
{
    //...
    struct XImpl *pimpl_;
};

// file x.cpp

#include "x.h"

struct XImpl
{
    // private stuff here ...
    static void *operator new(size_t)   { /*...*/ }
    static void *operator delete(void*) { /*...*/ }
};

X::X() : pimpl_( new XImpl ) { }
X::~X() { delete pimpl_; pimpl_ = 0; }