pImpl
pImpl Idiom in C++
|
Pointer to Implemantation Idiom in C++
The pImpl Idiom **(Pointer to IMPLementation)** is a technique used for separating implementation from the interface. It minimizes header exposure and helps programmers to reduce build dependencies by moving the private data members in a separate class and accessing them through an opaque pointer.
This is a C++ programming technique that removes implementation details of a class from its object representation by placing them in a separate class, accessed through an opaque pointer. This technique is used to construct C++ library interfaces with stable ABI and to reduce compile-time dependencies.
As can be seen in the diagram above, the User class has a single data member, d_ptr which is a pointer to the implementing class User::Private. The User::Private class is defined in the user_p.h file and is used only in the user.cpp file. The User class is defined in the user.h file and will constitute the API of the User class. The user of the User class does not need to know the definition of the User::Private class. It will use the public methods of the User class to access the private member data of the User::Private class (name() and setName() allow access to the private data name for example).
The pImpl library allows a library developer to use the pImpl Idiom easily, it provides a base API class, a base Private class, and a set of macros, similar to those used by Qt.
The pImpl lib is very strongly inspired by the implementation of the Qt library which uses a d pointer to the private class (implemantation) and a q pointer to the public class (API). The explanations below are taken from the D-Pointer page of the Qt wiki. The explanations are in the context of the Qt library but they are also valid for the pImpl lib and may be read to own wiki page in the context of the pImpl lib.
The pImpl lib provide a PimplClass that can be used as a base class for any class that needs to use the pImpl idiom. The private implementation class must be defined in the source file of the class that uses it or in a private header file (with _p suffix for example). PimplClass::Private is a friend of the class that uses it. Then, pImpl lib provide a set of macros that can be used to hide the private implementation class and the private implementation pointer.
Thus, the complete example of the User class using the pImpl lib is as follows:
user.h, the API of the User class:
user_p.h, the private implementation class of the User class:
user.cpp, the source file of the User class:
That corresponds to the following diagram:
An example of use of the User class is as follows (for Native platforms with io streams): examples/PimplUserPlatformIONative
and for Arduino platforms:
examples/PimplUserPlatformIOArduino
The pImpl lib uses std::unique_ptr, thus, this library can only be used on platforms with a STL implementation (see the list below):
Embedded
Desktop