Hiding Implementation with PIMPL
Hide implementation details behind a pointer-to-implementation idiom.
Hiding Implementation with PIMPL is a free C++ Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The PIMPL Idiom
PIMPL = "Pointer to IMPLementation." Move the class s private data to a separate impl struct, accessed via a pointer.
Why PIMPL?
Benefits:
- Hide implementation details from headers
- Reduce compile-time dependencies
- Maintain ABI stability when adding private members
- Allow swapping implementations
Basic Structure
The public class holds a pointer to an Impl struct defined only in the .cpp file.
// widget.h
class Widget {
public:
Widget();
~Widget();
void doSomething();
private:
struct Impl;
std::unique_ptr<Impl> pimpl_;
};Impl in the .cpp
The Impl struct holds all the actual data.
// widget.cpp
struct Widget::Impl {
std::string name;
int counter;
// ... anything else, freely
};
Widget::Widget()
: pimpl_(std::make_unique<Impl>()) {}
Widget::~Widget() = default; // must be in .cpp where Impl is complete
void Widget::doSomething() {
pimpl_->counter++;
}Destructor in the cpp
The destructor must be defined in the .cpp where Impl is complete. Otherwise unique_ptr cannot delete an incomplete type.
Special Member Functions
Copy, move, and assignment must also be explicitly declared if needed. The compiler-generated versions cannot work with an incomplete type in the header.
// widget.h
class Widget {
public:
Widget(const Widget& other);
Widget& operator=(const Widget& other);
Widget(Widget&&) noexcept;
Widget& operator=(Widget&&) noexcept;
~Widget();
};Performance Cost
PIMPL adds an indirection on every member access and a heap allocation. For frequently-called methods this can matter — measure to be sure.
Faster Builds
Headers that previously included std types or expensive dependencies can now be lean. Touch the .cpp without recompiling consumers.
PIMPL with Inheritance
Can be combined with inheritance, but adds complexity. The public class typically does not derive from anything; the Impl can use inheritance freely.
Variations
Alternatives and refinements:
- Fast PIMPL — inline storage with placement new
- Stable address — Impl stays allocated for the object s lifetime
- Type erasure — Impl can be polymorphic
Real-World Use
PIMPL is heavily used by:
- Qt (every widget is PIMPL)
- Many proprietary libraries
- Boost (in places)
When to Use
Use PIMPL when:
- You want ABI stability across versions
- Your headers transitively include too much
- You expose a public library API
When to Skip
Skip PIMPL when:
- The class is internal — no consumers depend on the header
- The performance overhead matters more than build times
- The class is small or rarely modified
Quick Check
Why must the destructor of a PIMPL class be defined in the .cpp file?
Recap
PIMPL hides implementation by moving private data into an Impl struct accessed via unique_ptr. It improves ABI stability and build times at the cost of indirection. Define special members in the .cpp where Impl is complete.
Frequently asked questions
Is the “Hiding Implementation with PIMPL” lesson free?
Yes — the full text of “Hiding Implementation with PIMPL” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.
What will I learn in “Hiding Implementation with PIMPL”?
Hide implementation details behind a pointer-to-implementation idiom. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C++ Academy?
No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Hiding Implementation with PIMPL” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C++ Academy lesson?
Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Header-Only vs Compiled Libraries
- API Versioning and ABI Stability
- Hiding Implementation with PIMPL
- Writing a Modern Header-Only Utility Library