Pimpl – Destruct Partial Declared Object

Pimpl is a common pattern in C++ design. It hides a class implementation details and keeps the public/protected interface unchanged when the implementation is changed.

Following codes illustrate how Pimpl pattern is implemented

// a.h
class A {
public:
     A();
     ~A();
public:
     void foo();                 // public/protected interfaces
private:
    class Pimpl;                 // partial (forward declare)
    friend class Pimpl;
    Pimpl* self;                 // opaque pointer
                                 // hold all private member/method
};

The implementation:

// a.cpp
#include "a.h"

// private implementation is declared in a.cpp only,
// changing a.cpp without a.h won't require re-compiling
// modules that reference a.h
class A::Pimpl {
    friend class A;
private:
    Pimpl() {}
    ~Pimpl() {}

    void foo() {}          // implementation of foo()

private:
    int props;              // private members of A
};

A::A()
 : self(new Pimpl())
{
}
A::~A()
{
    delete self;
}
void A::foo()
{
    self.foo();
}

When smart pointer is used, the code is changed like this

// a.h
   A();
   class Pimpl;
   std::unique<Pimpl> self;

// a.cpp
A::A() : self(new Pimpl()) {}

It wishes Pimpl* object is deleted automatically by smart pointer, so A::~A is not needed. Unfortunately, such code can not get compiled. Because A::Pimpl* is an opaque pointer (partial declared class) outside of a.cpp, it can NOT be created nor deleted outside of a.cpp.

Here is the proper implementation

// a.h
   A();
   ~A();       // do NOT declare as ~A() {}
   class Pimpl;
   std::unique<Pimpl> self;

// a.cpp
A::A() : self(new Pimpl()) {}  
A::~A() {}      // or in C++11 A::~A = default;

Because A::~A is defined in a.cpp, the compiler knows how to delete Pimpl* object.