Click here to Skip to main content
Click here to Skip to main content

Wrapper classes using C++ decorator templates

, 26 Nov 2003 CC (ASA 3U)
Rate this:
Please Sign up or sign in to vote.
Using template classes as decorators to build a flexible wrapper class framework


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.

Using the code

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

class CHandleWrapperImpl : public CHandleWrapperBase
    bool Open(LPCTSTR szFileName)
        // ...
    // ...

typedef      CWrapperT
        <    COperatorT
        <    CDefCtorT
        <    CTCtorShallowT
        <    CHandleWrapperImpl > > > >

To do

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.


  • 20 November 2003 - initial version
  • 24 November 2003 - minor correction: decorator is "object structural", not "object constructional" as I misremembered it


This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-Share Alike 3.0 Unported License


About the Author

Paul Bartlett
Technical Lead Google
United Kingdom United Kingdom
No Biography provided
Follow on   Twitter

Comments and Discussions

Generalspecial member functions PinmemberPaolo Messina28-Nov-03 6:28 
Since you are referencing constructors in the example code, I think it's worth mentioning that you cannot inherit some special member functions from the policy classes, such as non-default constructors and the assignment operator.
Even the default constructor is not actually inherited, but it gets called automatically for you by the compiler, with practically the same effect.
I must say that I don't remember well the matter about assignment, but I seem to remeber that it's not inherited.
Once I found myself with the desire to use different contructors, taken from policy classes, but I soon discovered that it wasn't possible. In the light of your article, that I would call "cascading" or "nested" policies, you could have the first class, the most external wrapper, with different constructors, but for the inner wrappers only default constructors.
Nice article, but a deeper study and maybe a comparison with other ideas or concepts would be nicer. Wink | ;)
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: special member functions PinmemberPaul Bartlett29-Nov-03 7:21 
GeneralRe: special member functions PinmemberPaolo Messina30-Nov-03 0:59 
GeneralPlease provide a demo application. PinmemberJohn M. Drescher27-Nov-03 5:55 
GeneralRe: Please provide a demo application. PinmemberPaul Bartlett27-Nov-03 23:26 
GeneralTemplates vs Interfaces Pinmemberemilio_g27-Nov-03 3:53 
GeneralAwesome!! Absolutely Awesome!! PinmemberWREY25-Nov-03 0:20 
GeneralRe: Awesome!! Absolutely Awesome!! PinmemberPaul Bartlett25-Nov-03 1:23 
GeneralDecorator PinmemberNemanja Trifunovic21-Nov-03 6:46 
GeneralRe: Decorator PinmemberPaul Bartlett23-Nov-03 23:41 
GeneralWTL as &quot;prior art&quot; PinmemberPaul Bartlett21-Nov-03 6:24 
GeneralPolicy-Based Design PinmemberGavin Greig21-Nov-03 4:16 
GeneralRe: Policy-Based Design PinmemberPaul Bartlett21-Nov-03 5:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150327.1 | Last Updated 27 Nov 2003
Article Copyright 2003 by Paul Bartlett
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid