Skip to content
AgileLogics
4 min read

The Pimpl Idiom

Prerequisites: Coroutines (C++20 overview)

"Pointer to implementation" hides a class's private members behind a forward-declared pointer, so changing them doesn't force every file that includes the header to recompile — a real, practical concern on large C++ codebases where compile times can be significant.

// widget.h — never needs to change when Impl's internals do
class Widget {
public:
    Widget();
    ~Widget();
    void doSomething();

private:
    class Impl;               // forward declaration only
    std::unique_ptr<Impl> pimpl;
};
// widget.cpp — the actual private details live here
class Widget::Impl {
public:
    int internalState = 0;
    void doSomethingImpl() { internalState++; }
};

Widget::Widget() : pimpl(std::make_unique<Impl>()) {}
Widget::~Widget() = default;
void Widget::doSomething() { pimpl->doSomethingImpl(); }

This trades a small runtime cost (one extra pointer indirection) for meaningfully faster incremental builds on large projects — a trade rarely worth making on a small program, but common in library-style code with many downstream consumers.