More C++ Idioms/Handle Body
From Wikibooks, the open-content textbooks collection
Contents |
[edit]
Handle Body
[edit] Intent
- Separating Interface from Implementation
- Insulate (prevent recompilation of) the clients of a class from the changes in its implementation detail.
[edit] Also Known As
- Bridge (Gamma et al.)
- Compilation Firewall
- Cheshire Cat
- PImpl (Pointer to Implementation) idiom
[edit] Motivation
In C++, a class is used for declaring interface as well as defining implementation. The private member functions, although not part of the "interface" of the class, must be declared in the class and are visible to the clients. Changes to the declaration of private data members, or signature of private functions require clients to recompile code. It is therefore useful to separate interface of a class from its implementation and prevent unnecessary recompilations.
[edit] Solution and Sample Code
Split an abstraction into two implementation classes. One takes on the role of an identifier and presents the class interface to the user. It is called the handle. The other class embodies the implementation and is called the body. The handle forwards member function invocations to the body.
// file String.hpp class StringRep; // Forward declaration only. class String { public: String(); String(const String &s); String &operator=(const String &s); ~String(); String(const char *s); . . . . private: StringRep *rep; // Pointer to implementation (pimpl) }; // file String.hpp ends here // file String.cpp #include "String.hpp" namespace { // Anonymous namespace class StringRep { // This should be in a separate source file than class String, so it can be compiled // separately, and made invisible to the client friend class String; StringRep(const char *s); ~StringRep(); int count; char *rep; }; } // anonymous namespace ends String::String() // constructors and everything else
Data changes can now safely be made to the implementation (body) without recompiling clients of the handle. The implementation becomes "more hidden" behind a pointer, hence the name: Compilation Firewall.
[edit] Consequences
- The extra level of indirection has a performance cost.
- This idiom doesn't address the issues of deep versus shallow copy and other runtime dynamics; See Counted Body, Envelope Letter.
- The idiom also makes inheritance less useful. See Handle Body Hierarchy to overcome this shortcoming.
- This idiom has limits in managing the dynamically allocated memory of the body class; see Counted Body.
- It also introduces the need for occasional redundant update to the handle and body classes, a problem addressed in part by Envelope Letter and Smart Pointer.
[edit] Known Uses
- Vast majority of non-trivial C++ software!
[edit] Related Idioms
[edit] References
- http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html#HandleBody
- Making Pimpl Easy -- Vladimir Batov
[edit] Copyright
Original copyright ©1998 Lucent Technologies, Bell Labs Innovations. All rights reserved. Permission granted to reprint verbatim for non-commercial use provided this copyright notice appears. (Contents edited for Wikibooks).