C++ Idioms


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

Pattern: Handle/Body

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.

Pattern: Counted 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.

Pattern: Detached Counted 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.

Pattern: Handle/Body Hierarchy

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.

Pattern: Envelope/Letter

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.

Pattern: Virtual Constructor

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.

Pattern: Concrete Data Type

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."

Pattern: Algebraic Hierarchy

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.

Pattern: Homogeneous Addition

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

Pattern: 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

Pattern: Promotion Ladder

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.

Pattern: Non-Hierarchical Addition

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.

Pattern: Type Promotion

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.