Questions tagged [pimpl-idiom]

The PIMPL idiom, also known as the compilation firewall or Cheshire Cat technique, is a "private implementation" technique useful in C++ and other similar statically compiled languages.

The idiom makes use of an opaque pointer to another object (usually of a nested class type) which provides the implementation. Member functions on the outer object forward to the implementation object, which is defined in a separate source file so that the implementation is not visible in the header defining the outer class. This is a special case of the Bridge pattern.

The term Cheshire Cat (because the body disappears leaving only a smile) is older, but the more common name PIMPL idiom was popularized by Herb Sutter in GOTW #24 (and revisited in GOTW #100 and #101).

Links:

Separating Interface and Implementation in C++ compares the PIMPL idiom to other related techniques.

281 questions
5
votes
7 answers

Private members in pimpl class?

Is there any reason for the implementation class as used in the pimpl idiom to have any private members at all? The only reason I can really think of is to protect yourself from yourself -- i.e. the private members serve to enforce some kind of…
Anne
  • 460
  • 3
  • 13
5
votes
1 answer

Alternative PImpl Idiom - advantages vs disadvantages?

The traditional PImpl Idiom is like this: #include struct Blah { //public interface declarations private: struct Impl; std::unique_ptr impl; }; //in source implementation file: struct Blah::Impl { //private…
LB--
  • 1,898
  • 1
  • 28
  • 72
4
votes
5 answers

Is there any advantage to the pimpl idiom with a templated class?

It is my understanding that the primary benefit of the pimpl idiom is to hide the data members in the implementation file instead of the header. However, templates need to be fully defined in the header in order for the compiler to instantiate them…
Oscar Korz
  • 2,387
  • 1
  • 16
  • 18
4
votes
2 answers

Are methods in the pimpl inlined?

Considering next simple example: The header: // a.hpp #ifndef A_HPP #define A_HPP #include class A { public: A(); int foo(); private: struct Imp; std::auto_ptr< Imp > pimpl; }; #endif // A_HPP The implementation : //…
BЈовић
  • 57,268
  • 38
  • 158
  • 253
4
votes
1 answer

Is changing the pointer type of a private member variable in an interface class binary compatible?

class Type1; class Type2; class __declspec(dllexport) Foo { public: Foo(); private: Type1 * m_p1; Type2 * m_p2; }; Can I replace Type1 with Type3 without breaking binary compatibility? Background: Unfortunately, this class does not use…
Fabian
  • 3,405
  • 2
  • 20
  • 52
4
votes
1 answer

Will the upcoming addition of modules in c++ fix/alleviate the need for the pimpl idiom?

The pimpl idiom, as far as I can tell, hides a private implementation behind a forward declared symbol name so it can be declared and used in the private cpp module. Example: https://cpppatterns.com/patterns/pimpl.html As far as I can tell, because…
JeffV
  • 47,302
  • 31
  • 96
  • 120
4
votes
4 answers

Incomplete type used in nested name specifier for Pimpl Idiom

I have this error for the following code incomplete type ‘Foo::Pimpl’ used in nested name specifier AnotherFoo.hpp struct AnotherFoo { void methodAnotherFoo(Foo &); }; AnotherFoo.cpp #include "Foo.hpp" #include "AnotherFoo.hpp" void…
Mihai
  • 760
  • 9
  • 30
4
votes
2 answers

Hiding variadic template implementation

I have some 3rdParty library with a method like this: bool Invoke(const char* method, Value* args, size_t nargs) It takes an array of its inner type (convertible to any primitive c++ types) and arg count as its inner params. In my code, I wrote…
Michael
  • 115
  • 4
4
votes
4 answers

C++: Creating a shared object rather than a shared pointer to an object

boost::shared_ptr really bothers me. Certainly, I understand the utility of such a thing, but I wish that I could use the shared_ptr as an A*. Consider the following code class A { public: A() {} A(int x) {mX = x;} virtual void…
JnBrymn
  • 21,527
  • 26
  • 95
  • 140
4
votes
0 answers

include a class that has std::unique_ptr as a field, while "T" is incomplete type

I created a tiny test case for std::unique with incomplete type B. Test.h #pragma once #include class B; //<--- compile error here class Test{ std::unique_ptr bPtr; //#1 need to move destructor's implementation to…
javaLover
  • 6,039
  • 2
  • 14
  • 57
4
votes
1 answer

Mocking classes that use Pimpl pattern

Let's say, I create a library libFoo that exposes an API this class class Book { public: Book(string const& title, string const& author); string const& title() const; string const& author() const; private: struct…
FCR
  • 1,027
  • 8
  • 21
4
votes
0 answers

using std::unique_ptr pimpl with explicit default destructor

When defining the following class class Foo { public: Foo (void); ~Foo (void) = default; protected: class FooImpl; std::unique_ptr _impl; //... }; Foo::Foo (void) : _impl (std::make_unique ()) { } I get the…
Daniel Heilper
  • 1,066
  • 1
  • 15
  • 31
4
votes
2 answers

Pimpl idiom implementation depending on a template function

Please consider the code below. The template parameter is a handler class that must provide the function bar(). I'm using the Pimpl idiom to hide the implementation details of Foo. Prior to having a template parameter the constructor definition was…
ksl
  • 3,901
  • 7
  • 50
  • 100
4
votes
1 answer

C++ Pimpl Idiom Incomplete Type using std::unique_ptr

I apologize for the large amount of code required to demonstrate the issue. I am having a problem using the pimpl idiom with std::unique_ptr. Specifically the problem seems to occur when one class (which has pimpl'ed implementation) is used as…
Matthew James Briggs
  • 1,635
  • 1
  • 18
  • 46
4
votes
1 answer

Overwriting operator new to merge PIMPL allocations

The PIMPL idiom is often used for public API of objects which sometimes also contain virtual functions. There, a heap allocation is often used to allocate the polymorphic object which is then stored in unique_ptr or similar. A famous example of this…
milianw
  • 4,621
  • 2
  • 33
  • 39