Pimpl (Pointer to implementation) is a common method used to decouple "the interface and implementation of a class". Pimpl has the following advantages:
- Reduced coupling of modules
- Reduce compilation dependencies and increase compilation speed
- Interface and implementation separation
In order to implement the PIMPL model, we first look at a common class design method.
If we are going to design a Book of books that contains the directory attributes and provides an external interface for printing the information, book is designed as follows:
classBook{public: void print();private: std::string m_Contents;}
Book users only need to know the print () interface, you can use the book class, it seems that everything is beautiful.
However, when one day, you find that book needs to add a title attribute, the change to the class is as follows:
classBook{public: void print();private: std::string m_Contents; std::string m_Title;}
Although the print () interface can still be used to output the information of a book directly, the user of the books class has to recompile all the code that contains the header file.
In order to hide the implementation details of the book class and implement a true separation between the interface and the implementation, you can use Pimpl mode.
/* public.h */class Book{public: Book(); ~Book(); void print();private: class BookImpl; BookImpl* m_p;};
For simple implementations, the book class omits copy constructors and copy assignment functions. In practical applications, these two functions should be defined.
In the external header file public.h , only the external interface of the book class is included, and the true implementation details are encapsulated into the Bookimpl class. To not expose the Bookimpl class, declare it as an inline class of the book class and declare it as private.
The header file for the Bookimpl class is as follows.
/* private.h */ #include "public .h " # Include <iostream >class book ::bookimpl {public : void print () ; private : std::string m_ Contents ; std : :string m_Title ; ;
The
private.h does not need to be provided to the user of the book class, so if you need to redesign the properties of the books class later, the outside world does not know about it, keeping the interface invariant and reducing the dependency between the header files.
/* book.cpp */ # Include "Private.h" #include "public.h" book :: Book () {m_p = new Bookimpl ();} book :: ~book () {delete m_p;} void book :: print () {M_p->print ();} /* then Bookimpl functions */ void book :: bookimpl :: print () {std :: cout << "Print from Bookimpl" << std :: Endl;}
Here's how to use the Book class's Interface:
/* main.cpp */#include "public.h"int main(){ Book book; book.print(); return0;}
Can be used to illustrate the role of the Pimpl pattern in the above book Class design:
Pimpl is also often referred to as the "compiler firewall."
Resources
- C + + Programming/idioms:pointer to implementation (PIMPL)
- The C + + Pimpl
- Compilation firewalls
- Pimpl mode
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Pimpl mode parsing for C + +