The beauty of private implementation (Pimpls)

December 20, 2008 at 12:06 pm 1 comment

In C++, when anything in a header file changes, all code that includes that header either directly or indirectly needs to be recompiled. Therefore, sometimes even a very trivial change might need to compile a lot of code. Also, when we usually declare both the public and private interfaces in the same c++ header file. Basically, the class declaration lets you peek at its private parts, which should actually be of no concern to the user of the class. Pimpl basically, decouples the interface of a class from its implementation (Bridge Pattern?). Any compile time dependencies are also eliminated. Lets see how.

Here is how we usually write our class declaration in a .h file

class MyClass
{
    public:
        MyClass();
        ~MyClass()
        int foo();
     private:
        int var;
        int bar();

};

Private Implementation or Pimpl is nothing but using an opaque pointer to hide the private members of a class. That is, the above can be written as:

class MyClassImpl; //Forward declare the Pimpl class
class MyClass
{
    public:
        MyClass();
        ~MyClass();
        int foo();
    private:
        MyClassImpl *m_pImpl;
};

In the code above the only visible private member in the class is the pimpl pointer. Now, lets take a look at the implementation in .cpp file.

class MyClassImpl
{
    public:
        int var;
        int bar()
        {
            return var * var;
        }
};

MyClass::MyClass() : m_pImpl(new MyClassImpl)
{ }

MyClass::~MyClass()
{
    delete m_pImpl;
}

int MyClass::foo()
{
    return m_pImpl->bar();
}

Any changes to the implementation class will not require recompilation of any other source file.  Only if changes are made to the public interface recompilation of other source file will be required.

Pimpl as other techniques comes with its own set of draw backs.

  1. Since the implementation is hidden in a separate class behind a pointer, every time this implementation class is created, memory needs to be allocated on the heap. And every time this class is destroyed, memory is freed. Compared to common operations like function calls, memory allocation and deallocation are relative expensive operations.
  2. Each access of a hidden member can require at least one extra indirection. In case the hidden member uses a back pointer then there will be multiple indirections.

So use the pimpl when you want to hide the implementation details of your class. However, make sure that you understand the performance penalties involved.


Entry filed under: Geeky stuff.

5 reasons you should become a freelancer 5 simple ways to start getting freelance work

1 Comment Add your own

  • 1. 如何加快C++代码的编译速度 | My Sky  |  April 24, 2010 at 7:32 am

    […] 使用Pimpl模式 Pimpl全称为Private Implementation。MySky传统的C++的类的接口与实现是混淆在一起的,而Pimpl这种做法使得类的接口与实现得以完全分离。MySky如此,只要类的公共接口保持不变,对类实现的修改始终只需编译该cpp;同时,该类提供给外界的头文件也会精简许多。MySky […]

    Reply

Leave a comment

Trackback this post  |  Subscribe to the comments via RSS Feed


Feeds