By: J.O. Coplien
Published in: PLoPD4
Pages: 167-197
Recasting of idioms in [Coplien92] into a pattern language that treats algebraic types. See an earlier version in [Coplien99a] and [Coplien99b]
Category: C++ Idioms
Summary: Recasting of idioms in [Coplien92] into a pattern language that treats algebraic types. See an earlier version in [Coplien99a] and [Coplien99b]
Url: http://www.bell-labs.com/~cope/Patterns/C++Idioms/EuroPLoP98.html
Pages: 171-173
To separate interface from implementation in C++ objects, split a class into two implementation classes. One, the handle, becomes an identifier and is the user interface. The other, the body, is the implementation. The handle forwards member function calls to the body.
Pages: 173-176
You're using Handle/Body. Assignment in C++ is defined recursively as member-by-member assignment with copying at the termination of the recursion. It would be more efficient if copying were rebinding. Add a reference count to the body class. Memory management is added to the handle class. Any operation that modifies the state of the body must make its own copy of the body and decrement the reference count of the original body.
Pages: 176-179
To overcome the overhead of an additional level of indirection when applying Counted Body to immutable classes, associate a shared count and a separate shared body with each instance of a common handle abstraction.
Pages: 179-182
You're using Handle/Body. Some classes have subtyping relationships and implementation-sharing relationships that do not correspond with each other. C++ ties implementation inheritance and representation inheritance together, and you may want to inherit each separately. Maintain separate inheritance hierarchies for handle classes and body classes. The base interface class contains a reference to the base implementation class.
Pages: 182-184
You're using Handle/Body or Counted Body to support multiple implementations of a single ADT. Derive all solution body classes from a common base class. Use the handle class as the common base class for alternate bodies. Make handle member functions virtual. Each alternative implementation derived from the handle class overrides suitable virtual functions.
Pages: 184-185
You're using Handle/Body. A client wants to create an object of an unspecified class in a class hierarchy. An object created from the classes in the hierarchy can be used interchangeably by the client. To create an object whose general type is known by the client but whose subtype characteristics must be chosen from context, use Envelope/Letter.
Pages: 186-187
Your design enumerates system classes, and you need to establish the lifetime and scope of the objects for those classes. When should you use "new" to allocate an object? Objects that represent real-world entities that live outside the program should be instantiated using "new."
Pages: 187-189
To construct the inheritance hierarchy for algebraic types, use Bridge [Gamma+95] to separate interface from implementation. The visible part is class Number. It contains a pointer to a representation part, which contains the representation and operations of the type, e.g., Complex, Real, Integer, Imaginary. Use State [Gamma+95] so Numbers can change type over time.
Pages: 189-190
You're using Algebraic Hierarchy. You need to distribute addition to the objects. How many addition operations are there, and where do they belong? Each type should only support homogeneous algebraic operations unless performance dictates otherwise. Use Promote and Add
Pages: 190-192
You're using Algebraic Hierarchy and Homogeneous Addition. To do heterogeneous addition, use run-time type identification (RTTI) to determine which of the two object types is more general. Promote and add the more specific type to the more general type using Promotion Ladder. Then use Homogeneous Addition. If one type is not a proper subtype of the other, use Non-Hierarchical Addition
Pages: 192-193
You're using Promote and Add. Where do you put the knowledge of type promotion? Each class should know how to promote itself to its own base class type. Promotions of more than two levels of the inheritance hierarchy can be handled by multiple successive promotions.
Pages: 193-194
You're using Promotion Ladder and Homogeneous Addition. Sometimes neither type is a subtype of the other, so neither can be promoted to the type of the other. Promote both to a more general type.
Pages: 195-196
Promotion between objects of different but related C++ types--zero or one of which is a built-in type or a type exported by a library for which you do not have the source--promote a class object type to a built-in type or a type exported from a library using a member conversion operator. Use constructors for all other promotions.