The PImpl idiom and the C++26 std:indirect type
PImpl (which stands for Pointer to implementation) is a programming tehnicque to remove implementation details from a class by placing them in a separate class that is accessed through an opaque pointer. Its purpose is to separate interfaces and implementations and minimize compile-time dependencies. In this article, weβll at how the PImpl idiom is typically implemented in C++ and how C++26 simplifies its implementation.
We can implement the Pimpl idiom using raw pointers and abiding to the Rule of Five. This is a guideline that says that when a class defines a special member function (for resource management) it should define all five of them (destructor, copy constructor, copy assignment operator, move constructor, move assignment operator).
To demonstrate this, we will use a widget that represents a UI element that has a label and can be clicked and on each click a counter is incremented. Therefore, a widget would have a counter and a label but these are implementation details that are hidden behind an implementation class.
This Widget class definition looks as follows:
The Widget::Impl class is an incomplete type here. Itβs forward declared and defined in the .cpp file. The Widget class keeps a pointer to an object of this type.
The Widget class defines all five special member functions. The move constructor and assignment operator are defined noexcept because they just copy/delete objects and nothing should throw. Moreover, itβs a performance issue because a container such as std::vector<Widget> will only move elements during reallocation if the move constructor is noexcept ; otherwise it falls back to copying to preserve its strong exception guarantee.