Post

HN
Hacker News

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.