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.