PImpl Idiom

First introduced in CS247.

Links

OMG I saw this in NVIDIA codebase!!

Use Case #1: Ensure Strong Guarantee

Introduced after diving into Exception Safety, and how other methods couldn’t work for strong guarantee.

struct CImpl { // "Impl" class has the fields
	A a;
	B b;
};
 
class C {
	unique_ptr<CImpl> pImpl;
	public:
		void f() {
			unique_ptr<CImpl> temp = make_unique<CImpl>(*pImpl);
			temp->a.g();
			temp->b.h();
			std::swap(temp, pImpl); // guaranteed nothrow
		}
};

This is the strong guarantee - if a.g() or b.h() throw - all work is done on temp, so we’re fine.

Otherwise, swap will always succeed f will do its job.

Use Case 2: Reduce Compilation Dependencies

PImpl Idiom can also be used in some scenarios for reducing compilation dependencies.

Typically: C.h

class C {
	A a; // If any of the private fields change, anbody who #include "C.h" must recompile
	B b;
};

On the other hand: CImpl.h

struct CImpl {
	A a;
	B b;
};

C.h

class CImpl;
class C {
	unique_ptr<CImpl> pImpl;
	...
};

Now, if cImpl changes only C.cc must recompile. Because we only use a forward declaration in C.h no recompilation.

Finally - we could make CImpl a polymorphic class - swap out implementations at runtime - the Bridge Pattern.