C++ TutorialBasic input/output in c++C++ AlignmentC++ Argument Dependent Name LookupC++ Arithmitic MetaprogrammingC++ ArraysC++ Atomic TypesC++ AttributesC++ autoC++ Basic Type KeywordsC++ Bit fieldsC++ Bit ManipulationC++ Bit OperatorsC++ Build SystemsC++ C incompatibilitiesC++ C++11 Memory ModelC++ Callable ObjectsC++ Classes/StructuresC++ Client server examplesC++ Common compile/linker errors (GCC)C++ Compiling and BuildingC++ Concurrency with OpenMPC++ Const CorrectnessC++ const keywordC++ Constant class member functionsC++ constexprC++ ContainersC++ Copy ElisionC++ Copying vs AssignmentC++ Curiously Recurring Template Pattern (CRTP)C++ Date and time using chrono headerC++ Debugging and Debug-prevention Tools & TechniquesC++ decltypeC++ Digit separatorsC++ EnumerationC++ ExceptionsC++ Explicit type conversionsC++ Expression templatesC++ File I/OC++ Floating Point ArithmeticC++ Flow ControlC++ Fold ExpressionsC++ Friend keywordC++ function call by value vs. call by referenceC++ Function OverloadingC++ Function Template OverloadingC++ Futures and PromisesC++ Header FilesC++ Implementation-defined behaviorC++ Inline functionsC++ Inline variablesC++ IterationC++ IteratorsC++ KeywordsC++ LambdasC++ Layout of object typesC++ Linkage specificationsC++ LiteralsC++ LoopsC++ Memory managementC++ MetaprogrammingC++ Move SemanticsC++ mutable keywordC++ MutexesC++ NamespacesC++ Non-Static Member FunctionsC++ One Definition Rule (ODR)C++ Operator OverloadingC++ operator precedenceC++ OptimizationC++ Overload resolutionC++ Parameter packsC++ Perfect ForwardingC++ Pimpl IdiomC++ PointersC++ Pointers to membersC++ PolymorphismC++ PreprocessorC++ ProfilingC++ RAII: Resource Acquisition Is InitializationC++ Random number generationC++ Recursive MutexC++ Refactoring TechniquesC++ ReferencesC++ Regular expressionsC++ Resource ManagementC++ Return Type CovarianceC++ Returning several values from a functionC++ RTTI: Run-Time Type InformationC++ Scopes

C++ Pimpl Idiom

From WikiOD

Remarks[edit | edit source]

The pimpl idiom (pointer to implementation, sometimes referred to as opaque pointer or cheshire cat technique), reduces the compilation times of a class by moving all its private data members into a struct defined in the .cpp file.

The class owns a pointer to the implementation. This way, it can be forward declared, so that the header file does not need to #include classes that are used in private member variables.

When using the pimpl idiom, changing a private data member does not require recompiling classes that depend on it.

Basic Pimpl idiom[edit | edit source]


In the header file:

// widget.h

#include <memory>  // std::unique_ptr
#include <experimental/propagate_const>

class Widget
        void DoSomething();

        // the pImpl idiom is named after the typical variable name used
        // ie, pImpl:
        struct Impl;                    // forward declaration
        std::experimental::propagate_const<std::unique_ptr< Impl >> pImpl;  // ptr to actual implementation

In the implementation file:

// widget.cpp

#include "widget.h"
#include "reallycomplextype.h" // no need to include this header inside widget.h

struct Widget::Impl
    // the attributes needed from Widget go here
    ReallyComplexType rct;

Widget::Widget() :

Widget::~Widget() = default;

void Widget::DoSomething()
    // do the stuff here with pImpl

The pImpl contains the Widget state (or some/most of it). Instead of the Widget description of state being exposed in the header file, it can be only exposed within the implementation.

pImpl stands for "pointer to implementation". The "real" implementation of Widget is in the pImpl.

Danger: Note that for this to work with unique_ptr, ~Widget() must be implemented at a point in a file where the Impl is fully visible. You can =default it there, but if =default where Impl is undefined, the program may easily become ill-formed, no diagnostic required.