I see a lot of source code that uses PImpl idiom in C++. I assume Its purpose is to hide the private data/type/implementation, so it can remove dependence, and then reduce compile time and header include issue.
But interface/pure-abstract classes in C++ also have this capability, they can also be used to hide data/type/implementation. And to let the caller just see the interface when creating an object, we can declare a factory method in the interface's header.
The comparison is:
Cost:
The interface way cost is lower, because you don't even need to repeat the public wrapper function implementation
void Bar::doWork() { return m_impl->doWork(); }, you just need to define the signature in the interface.Well understood:
The interface technology is better understood by every C++ developer.
Performance:
Interface way performance is not worse than PImpl idiom, both requires an extra memory access. I assume the performance is same.
Following is the pseudocode to illustrate my question:
// Forward declaration can help you avoid include BarImpl header, and those included in BarImpl header.
class BarImpl;
class Bar
{
public:
// public functions
void doWork();
private:
// You don't need to compile Bar.cpp after changing the implementation in BarImpl.cpp
BarImpl* m_impl;
};
The same purpose can be implemented using interface:
// Bar.h
class IBar
{
public:
virtual ~IBar(){}
// public functions
virtual void doWork() = 0;
};
// to only expose the interface instead of class name to caller
IBar* createObject();
So what's the point of PImpl?
Implclass will not break theABI, but add public function in interface will breakABI. – ZijingWu Oct 03 '13 at 12:27unordered_set), without PImpl, I need to#include <unordered_set>inMyClass.h. With PImpl, I only need to include it in the.cppfile, not the.hfile, and therefore everything else that includes it... – Martin C. Martin May 18 '17 at 13:54unordered_setonly to the actual implementation of the interface, which is not included much. Everywhere else, where you use your class, you use it only via the interface, which does not have said include. – CygnusX1 Aug 22 '20 at 15:02