Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Use the Pimpl Idiom to Reduce Compilation Time and Enhance Encapsulation : Page 3

Changes in the implementation details of a single infrastructure class don't have to trigger a wholesale recompilation of the numerous classes referring to the modified class. Find out how applying the Pimpl idiom can help you reduce compilation time and enhance encapsulation.


advertisement
Apply the Pimpl Idiom
Originally introduced by James Coplien in 1992, the Pimpl idiom has undergone several revisions and name changes. The name Pimpl itself stands for "impl" with the prefix "p", following the Hungarian naming convention. Pimpl is a method of hiding implementation details by moving private members (both data and functions) of a class into an internal private struct.

In String.h, you provide only forward declaration of this internal struct (called StringImpl in this example) and add an opaque pointer to it. The modified String.h file now looks like this:

//+++ file String.h after applying the Pimpl idiom #include <iosfwd> class String { public: String (); ~String(); //... std::size_t length() const; std::ostream & operator << (std::ostream& s) const; //... private: struct StringImpl; //fwd declaration of internal struct StringImpl * pimpl; //opaque pointer };

In the corresponding String.cpp file (which, unlike String.h, is compiled only once), you add the definition of struct StringImpl along with the rest of String's member functions:


//+++file String.cpp #include <vector> #include "Lock.h" #include "String.h" struct String::StringImpl { std::vector<char> vc; std::size_t len; Lock lck; }; String::String(): pimpl (new String::StringImpl) {} String::~String() {delete pimpl; } //..additional member functions

Every String object allocates its own StringImpl object dynamically during construction. String's member functions access the StringImpl members using the pointer pimpl:

//+++file String.cpp std::size_t String::length() const { return pimpl->len; }

Now you can modify StringImpl (say by replacing the vector <char> data member with char *) without recompiling the entire project.

A Pimpl in Time
In essence, the Pimpl idiom moves code from a header file that gets compiled several times (once for each translation unit that #includes it), into a single source file which gets compiled only once. The two major advantages of this are:

  • You can freely change the implementation details of String without having to recompile code that uses that class.
  • Datatypes that are used only as private members (in this example: std::vector, Lock and std::size_t) need no longer be defined in String.h. This means that you can remove extra #includes from String.h, thus reducing compilation time.

If the original class contained many private members, and its header file is #included in numerous, separately-compiled files, applying this idiom can reduce compilation time significantly. That said, you already know that there's no such thing as a free lunch. While a Pimpled class may reduce compilation time and enhance encapsulation, it exacts performance penalties:

  • Each construction and destruction allocates and release memory dynamically.
  • String accesses its hidden data members using a pointer, whereas the non-Pimpled version accesses them directly.
Therefore, it's always best to experiment with a few key-classes in a project and learn how this affects your project's build-time.



Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap