This time lets briefly look at three structural idioms discussed in Coplien's book, Advanced C++ programming styles and idioms.
Handle and Body: Handle and body are logically one entity but physically two. This separation allows handle to be much smaller in size than the body. Handle and body are both classes. Because they are logically same entity, there are several consequences: handle can be passed instead of body wherever body is required (efficient). To be logically same, handle and body needs to have exactly same interface. Any addition to body class interface needs a change in the handle class (maintenance). Handle class delegates all function calls to the body. (extra function call). Handle manages memory and the body manages the abstraction. This type of structure is typically used in reference counting. Though hidden from the client, body class pollutes the global namespace. Important thing to note here is that though, both the classes are in global namespace the instance of the body class is only accesible from within the handle class. body class is all private and handle is a friend of body. Note that both handle and body need to be classes.
Then why put the body class in the global namespace? Lets put it inside the handle class. Call this type of structure Envelope/Letter class idiom.
e.g.
class String_Reprentation { char str[5000]; long count; } (Body)
class String { String_Reprentation *rep; } (Handle)
The problem of mirroring interfaces in the handle and body classes mentioned above can be solved using a cool C++ feature: operator ->. Define an overloaded dereference operator (arrow operator) in the handle class which returns a pointer to body.
String_Representation * String::operator -> ();
Note that most new string operations can be implemented as String_Representation member functions: the handle class String gets these operations automatically throught overloaded arrow operator. Add reference counting to it for more flavor. Call it Counted Pointer idiom! Also note that String_Representation interface can't be private.
More info: http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html
Handle and Body: Handle and body are logically one entity but physically two. This separation allows handle to be much smaller in size than the body. Handle and body are both classes. Because they are logically same entity, there are several consequences: handle can be passed instead of body wherever body is required (efficient). To be logically same, handle and body needs to have exactly same interface. Any addition to body class interface needs a change in the handle class (maintenance). Handle class delegates all function calls to the body. (extra function call). Handle manages memory and the body manages the abstraction. This type of structure is typically used in reference counting. Though hidden from the client, body class pollutes the global namespace. Important thing to note here is that though, both the classes are in global namespace the instance of the body class is only accesible from within the handle class. body class is all private and handle is a friend of body. Note that both handle and body need to be classes.
Then why put the body class in the global namespace? Lets put it inside the handle class. Call this type of structure Envelope/Letter class idiom.
e.g.
class String_Reprentation { char str[5000]; long count; } (Body)
class String { String_Reprentation *rep; } (Handle)
The problem of mirroring interfaces in the handle and body classes mentioned above can be solved using a cool C++ feature: operator ->. Define an overloaded dereference operator (arrow operator) in the handle class which returns a pointer to body.
String_Representation * String::operator -> ();
Note that most new string operations can be implemented as String_Representation member functions: the handle class String gets these operations automatically throught overloaded arrow operator. Add reference counting to it for more flavor. Call it Counted Pointer idiom! Also note that String_Representation interface can't be private.
More info: http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html
Comments