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?

  1. 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.
  2. Reducing recompilation of all files, on every code change in single file.
  3. Reducing overall compilation time of project.
  4. 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

Popular posts from this blog

Non-virtual interface idiom (NVI)

Architectural patterns => Mud to structure => layers.

Architectural style -> Adoptable system -> Reflection.