Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Pimpl Idiom in practice

There have been a few questions on SO about the pimpl idiom, but I'm more curious about how often it is leveraged in practice.

I understand there are some trade-offs between performance and encapsulation, plus some debugging annoyances due to the extra redirection.

With that, is this something that should be adopted on a per-class, or an all-or-nothing basis? Is this a best-practice or personal preference?

I realize that's somewhat subjective, so let me list my top priorities:

  • Code clarity
  • Code maintainability
  • Performance

I always assume that I will need to expose my code as a library at some point, so that's also a consideration.

EDIT: Any other options to accomplish the same thing would be welcome suggestions.

like image 213
Ryan Emerle Avatar asked May 09 '09 14:05

Ryan Emerle


People also ask

What does Pimpl mean?

1 : a small inflamed elevation of the skin : papule especially : pustule. 2 : a swelling or protuberance like a pimple. Other Words from pimple. pimpled \ -​pəld \ adjective. pimply \ -​p(ə-​)lē \ adjective.

Why is Pimpl an idiom?

The PIMPL Idiom (Pointer to IMPLementation) is a technique for implementation hiding in which a public class wraps a structure or class that cannot be seen outside the library the public class is part of. This hides internal implementation details and data from the user of the library.

When to use PIMPL idiom?

The PImpl Idiom (Pointer to IMPLementation) is a technique used for separating implementation from the interface. It minimizes header exposure and helps programmers to reduce build dependencies by moving the private data members in a separate class and accessing them through an opaque pointer.


2 Answers

I'd say that whether you do it per-class or on an all-or-nothing basis depends on why you go for the pimpl idiom in the first place. My reasons, when building a library, have been one of the following:

  • Wanted to hide implementation in order to avoid disclosing information (yes, it was not a FOSS project :)
  • Wanted to hide implementation in order to make client code less dependent. If you build a shared library (DLL), you can change your pimpl class without even recompiling the application.
  • Wanted to reduce the time it takes to compile the classes using the library.
  • Wanted to fix a namespace clash (or similar).

None of these reasons prompts for the all-or-nothing approach. In the first one, you only pimplize what you want to hide, whereas in the second case it's probably enough to do so for classes which you expect to change. Also for the third and fourth reason there's only benefit from hiding non-trivial members that in turn require extra headers (e.g., of a third-party library, or even STL).

In any case, my point is that I wouldn't typically find something like this too useful:

class Point {   public:           Point(double x, double y);     Point(const Point& src);     ~Point();     Point& operator= (const Point& rhs);      void setX(double x);     void setY(double y);     double getX() const;     double getY() const;    private:     class PointImpl;     PointImpl* pimpl; } 

In this kind of a case, the tradeoff starts to hit you because the pointer needs to be dereferenced, and the methods cannot be inlined. However, if you do it only for non-trivial classes then the slight overhead can typically be tolerated without any problems.

like image 170
Reunanen Avatar answered Oct 09 '22 03:10

Reunanen


One of the biggest uses of pimpl ideom is the creation of stable C++ ABI. Almost every Qt class uses "D" pointer that is kind of pimpl. This allows performing much easier changes withot breaking ABI.

like image 20
Artyom Avatar answered Oct 09 '22 03:10

Artyom