![]() |
Languages »
C / C++ Language »
Templates
Intermediate
Wrapper classes using C++ decorator templatesBy Paul BartlettUsing template classes as decorators to build a flexible wrapper class framework |
VC6, VC7, VC7.1, Windows, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
This article presents a new (to me at least) spin on the decorator pattern, and demonstrates its use in building a flexible framework of wrapper classes.
The "Gang of Four" describe the decorator pattern as an object structural one, in that it endows an existing object with extra behaviour dynamically at runtime. Here we use templates to add behaviour to a class statically at compile-time.
This article is an extension of a blog post I wrote shortly after "discovering" the technique.
The code is provided mainly to illustrate the use of "decorator templates" as a flexible composition technique, though some portions of the code itself may obviously be of use to anyone else building wrapper classes.
The basic form of a decorator template is as follows:
template < [ class CPolicy1 , ... ] typename TBase > class CDecoratorT : public TBase { // ... };
Because TBase can itself be a decorated class, this allows arbitrary levels of nesting.
Initially the TBase template parameter was first, followed by the optional policy classes. Though this seemed logical, it led to the decorator template and its policy class(es) becoming "separated" when nesting was used.
The wrapper framework itself takes advantage of this nesting by building up the wrapper in various layers:
| Layer | Purpose | Type of class used | Example |
| Storage | Provides storage for the underlying type | Template | CTypeHolderT |
| Generic per-type functionality | Uses policy classes to select the correct implementation of generic functionality for a given wrapped type | Decorator template | CDeepCopyableT |
| Type-specific functionality | Hand-written classes to add useful methods to the wrapper | Normal or possibly template | CHandleWrapperImpl |
| Generic per-wrapper functionality | Provides implementations of optional functionality, to be called either by the "client" class (see below) or externally | Decorator template | CDeepCopyCtorT |
| "Client" | Provides implementation of "non-inheritable" methods (e.g. constructors) in terms of the previous layer. The nature of C++ templates mean that there will be a compilation error if and only if the method is used but not defined | Template | CWrapperT |
There are also two other categories of classes which are not layers:
| Category | Purpose | Type of class used | Example |
| Policy classes | Used by decorator templates to provide a type-specific implementation of generic behaviour | Normal or template | CCloseHandle |
| Miscellaneous helpers | Various | Usually template | CAcquirerT |
An example usage would therefore be:
typedef CDestroyableT < CCloseHandle, CDeepCopyableT < CDuplicateHandle, CInvalidatableT < CInvalidValueT< HANDLE , NULL >, CShallowCopyableT < CCopyByAssignmentT< HANDLE >, CTypeHolderT < HANDLE > > > > > CHandleWrapperBase; class CHandleWrapperImpl : public CHandleWrapperBase { bool Open(LPCTSTR szFileName) { // ... } // ... }; typedef CWrapperT < COperatorT < CDefCtorT < CTCtorShallowT < CHandleWrapperImpl > > > > CHandleWrapper;
This is merely a brief overview of the code, which is unfortunately rather short of meaningful comments. It is therefore my intention either to update the code with some useful comments (possibly Doxygen-style ones), or possibly extend the article to give a full walkthrough of the code. Any feedback as to which people would prefer would be most welcome, as of course would any questions, suggestions, etc. about the code itself.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 26 Nov 2003 Editor: Nishant Sivakumar |
Copyright 2003 by Paul Bartlett Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |