Click here to Skip to main content
15,880,972 members
Articles / Programming Languages / C++
Article

Wrapper classes using C++ decorator templates

Rate me:
Please Sign up or sign in to vote.
3.71/5 (7 votes)
26 Nov 2003CC (ASA 3U)2 min read 91.9K   652   17   13
Using template classes as decorators to build a flexible wrapper class framework

Introduction

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.

Background

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:

LayerPurposeType of class usedExample
StorageProvides storage for the underlying typeTemplateCTypeHolderT
Generic per-type functionalityUses policy classes to select the correct implementation of generic functionality for a given wrapped typeDecorator templateCDeepCopyableT
Type-specific functionalityHand-written classes to add useful methods to the wrapperNormal or possibly templateCHandleWrapperImpl
Generic per-wrapper functionalityProvides implementations of optional functionality, to be called either by the "client" class (see below) or externallyDecorator templateCDeepCopyCtorT
"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 definedTemplateCWrapperT

There are also two other categories of classes which are not layers:

CategoryPurposeType of class usedExample
Policy classesUsed by decorator templates to provide a type-specific implementation of generic behaviourNormal or templateCCloseHandle
Miscellaneous helpersVariousUsually templateCAcquirerT

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;

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.

History

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

License

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


Written By
Technical Lead Google
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalspecial member functions Pin
Paolo Messina28-Nov-03 5:28
professionalPaolo Messina28-Nov-03 5:28 
GeneralRe: special member functions Pin
Paul Bartlett29-Nov-03 6:21
Paul Bartlett29-Nov-03 6:21 
GeneralRe: special member functions Pin
Paolo Messina29-Nov-03 23:59
professionalPaolo Messina29-Nov-03 23:59 
Maybe my observation was more about policies than specifically about your article.

What you say is true, you can always implement copy constructor or copy operator as calls to other functions, because you know the function prototype "a priori". But if you need special constructors, like I did in a project of mine, this approach doesn't work simply because you don't know how the policy base class must be constructed.
Maybe this goes beyond the "policy" definition, and maybe in some cases you can split the construction in two steps, a default ctor and a "create" function, but in other cases you can't and you're left with the problem.

I just wanted to point this out for anyone who may think to use any member function in policy classes: custom contructors can't be used, unless the derived template class knows about them (but this is a bit more specific than "generic" programming). Wink | ;)

Paolo

------
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)
GeneralPlease provide a demo application. Pin
John M. Drescher27-Nov-03 4:55
John M. Drescher27-Nov-03 4:55 
GeneralRe: Please provide a demo application. Pin
Paul Bartlett27-Nov-03 22:26
Paul Bartlett27-Nov-03 22:26 
GeneralTemplates vs Interfaces Pin
Emilio Garavaglia27-Nov-03 2:53
Emilio Garavaglia27-Nov-03 2:53 
GeneralAwesome!! Absolutely Awesome!! Pin
WREY24-Nov-03 23:20
WREY24-Nov-03 23:20 
GeneralRe: Awesome!! Absolutely Awesome!! Pin
Paul Bartlett25-Nov-03 0:23
Paul Bartlett25-Nov-03 0:23 
GeneralDecorator Pin
Nemanja Trifunovic21-Nov-03 5:46
Nemanja Trifunovic21-Nov-03 5:46 
GeneralRe: Decorator Pin
Paul Bartlett23-Nov-03 22:41
Paul Bartlett23-Nov-03 22:41 
GeneralWTL as &quot;prior art&quot; Pin
Paul Bartlett21-Nov-03 5:24
Paul Bartlett21-Nov-03 5:24 
GeneralPolicy-Based Design Pin
Gavin Greig21-Nov-03 3:16
Gavin Greig21-Nov-03 3:16 
GeneralRe: Policy-Based Design Pin
Paul Bartlett21-Nov-03 4:45
Paul Bartlett21-Nov-03 4:45 

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

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