pImpl: Pointer-to-Implementation
The pImpl idiom is a very useful way to decouple the interface of a class from its implementation.
Normally, a class definition must contain member variables as well as methods, which may expose too much information. For example, a member variable may be of a type defined in a header that we don't wish to include everywhere.
The windows.h
header is a prime example here. We may wish to wrap a HANDLE
or another Win32 type inside a class, but we can't put a HANDLE
in the class definition without having to include windows.h
everywhere the class is used.
The solution then is to create a Private IMPLementation or Pointer-to-IMPLementation of the class, and let the public implementation store only a pointer to the private one, and forward all member methods.
For example:
class private_foo; // a forward declaration a pointer may be used
// foo.h
class foo {
public:
foo();
~foo();
void bar();
private:
private_foo* pImpl;
};
// foo.cpp
#include whichever header defines the types T and U
// define the private implementation class
class private_foo {
public:
void bar() { /*...*/ }
private:
T member1;
U member2;
};
// fill in the public interface function definitions:
foo::foo() : pImpl(new private_foo()) {}
foo::~foo() { delete pImpl; }
void foo::bar() { pImpl->bar(); }
The implementation of foo
is now decoupled from its public interface, so that
- it can use members and types from other headers without requiring these dependencies to be present when the class is used, and
- the implementation can be modified without forcing a recompile of the code that uses the class.
Users of the class simply include the header, which contains nothing specific about the implementation of the class. All implementation details are contained inside foo.cpp
.