Pimpl idiom (pointer to implementation).
In object oriented programming, bunch of objects are talking to
each other, to complete assigned tasks. It is very common, that one class contain another class as its data member (yes I am talking about composition).
For example, we have car object and engine object. Car has
engine, so car create engine object as its class data member (an example of composition). Now if I include some more functionality into engine
class and introduce more data member in engine class, I have to recompile my
car class though I have not changed anything in car class. Object
size change of engine class results, re-compilation of car class, because overall car's object size
will change accordingly (as it contains engine class).
So the problem is, whenever you are changing your implementation
class (or any class used by other classes), you have to recompile your code
every time. Anyone will say this is not a good idea. How to make my class less
dependent on others.
How to fix that?
Use pimpl idiom, create all together a separate class for
implementing the core logic. Have a pointer to implementation class. Now if
implementation class changes its object size, it doesn’t matter as size of
pointer is not going to change.
Now other classes don’t have to worry if we add one more private field/member in our implementation class. No recompilation required.
Benefits?
- We are hiding implementation class and improving the encapsulation, so that if we change our algorithm at later stage, it will not impact our client code.
- Reducing recompilation of all files, on every code change in single file.
- Reducing overall compilation time of project.
- If you need swap or = operations on your class, it is good idea to use pimpl, because instead of worrying deep copy and other problems, now you just have to swap two pointers :)
Oh sounds good, shall I apply it to all classes?
I would not recommend that, if you are a library developer
and your implementation file has many algorithms, then you shall use it, as it
likely to change in every release. We try to solve complex problems through
better algorithms and change our internal implementations. But changing
internal implementation should not affect rest of the code, so those internal
implementation classes are the best candidate for pimpl idiom, not all classes.
Example -
/************************************************************************************** /* /* demonstrating Pinpl idiom. (pointer to implementation) /* (c) 2016 Kunjesh Singh Baghel, All Rights Reserved. /* https://sites.google.com/site/kunjeshsinghbaghel/ ***************************************************************************************/ //************************************************************************************* // Header files #include<iostream> using namespace std; //************************************************************************************* //Global variables and functions //************************************************************************************* // Class class MyPublicClass { public: MyPublicClass(); void myAlgorithm(); private: class MyImplClass; MyImplClass* m_myImplClass; }; //************************************************************************************* // Class class MyPublicClass::MyImplClass { public: MyImplClass(int inputValue1, int inputValue2, int inputValue3): m_placeholder1(inputValue1), m_placeholder2(inputValue2), m_placeholder3(inputValue3) {} void myAlgorithm() { cout<< "inside implementation class" << endl; } private: int m_placeholder1, m_placeholder2, m_placeholder3; }; /////////////////////////////////////////////////////////////////////////////////////// MyPublicClass::MyPublicClass() { m_myImplClass = new MyImplClass(1,2,3); } /////////////////////////////////////////////////////////////////////////////////////// void MyPublicClass::myAlgorithm() { m_myImplClass->myAlgorithm(); } //************************************************************************************* // Main functions int main(int argc, char** argv) { MyPublicClass myPublicClassObject; myPublicClassObject.myAlgorithm(); return 0; } ///////////////////////////////////////////////////////////////////-------------OutPut /* $ ./a.exe inside implementation class */
Thanks for reading it. To read more on design patterns and basic design principles please see my web page. You can also join me on FB or on G++. Please drop comments for any question related to this blog.
Comments
Post a Comment