Click here to Skip to main content
13,833,837 members
Click here to Skip to main content
Add your own
alternative version


28 bookmarked
Posted 24 Jul 2004
Licenced CPOL

Dynamic Class Factory

, 18 Nov 2018
Rate this:
Please Sign up or sign in to vote.
An article about class factory with dynamic subscription / auto registration


This is the article about possible implementation of class factory, which uses dynamic subscription. It allows creation of objects based on custom criterion, useful, for example, in parsing of XML or other type of data, or for creating objects loaded from database.


Has it happened to you that you had to write a huge switch command doing nothing but creating new objects? And include all the headers for all the objects into one CPP file? And then, when you made a small change in one of the headers, it took ages to compile?

Something similar to this:

CBase* pBase(NULL);
switch (type_variable)
    case obj1: pBase = new CBaseDerivate1();break;
    case obj2: pBase = new CBaseDerivate2();break;


    case objN: pBase = new CBaseDerivateN();break;

or worse:

CBase* pBase(NULL);

if (!strcmp(string_for_type, "Type1")) pBase = new CBaseDerivate1();
else if (!strcmp(string_for_type, "Type2")) pBase = new CBaseDerivate2();
else if (!strcmp(string_for_type, "TypeN")) pBase = new CBaseDerivateN();

P.S.: This could be even worse when complex conditions are used.

Tackling the Problem

When I was implementing an XML parser and loading stored objects from DB, I got a lot of similar constructions. Well, I got tired of it quite soon. After becoming more experienced, I started to think about it. And recently, when I needed to use similar code again, I found out the following approach...

What I actually want is a 'class factory', something that would create classes for me.

CBase* pBase = CClassFactory::CreateInstance(type_variable);

I could hide object construction into a separate class factory. In ATL, class factory uses a static array of available classes with pointer into CreateInstance function. New entries are added by the wizard. But the problem with headers and compilation (still lot of the includes would go into CPP) remains here.

Then, I came up with an idea - what about static array/map? But populated dynamically? And all classes would 'register' their creator function themselves. Would it be possible? How?

The idea of static array/map populated dynamically sounded very strange at the beginning, but what about declaring std::map/vector as static? And populate it by some clever mechanism later... Yep, we can do it.

Now, for the self registration bit. It took me some moments to come up with the solution, but it was simple (once found). We can sneak some code into initialization of static dummy variable... Like:

int CMyClass::iDummy = 
    ClassFactory::RegisterCreatorFunction(key, CMyClass::Creator)

where function RegisterCreatorFunction will return any integer and add creator function pointer (must be static too) into array/map.

OK, you might say... This seems quite easy to do.

So, now we have:

static std::map<key, pointer_to_create_function> mapOfCreators;

class CBaseDerivate1: public CBase
    static CBase* create_function();
    static key DummyVariable;

in header and

key CBaseDerivate1::DummyVariable = RegisterCreatorFunction(key, 

in CPP file.

If you try it, there is a 50% chance that it will work. Yes, there is a catch: it might happen that static dummy will be initialized before the initialization of static array/map. And this whole code will throw an unhandled exception. But there is a cure for it - we won't access static array directly but by static get function, so the array/map will be created at the first access...

So instead of:

static std::map<key, pointer_to_create_function> mapOfCreators;

we need a 'get' function:

static std::map<key, pointer_to_create_function> * get_mapOfCreators()
    static std::map<key, pointer_to_create_function> _mapOfCreators;
    return &_mapOfCreators;


And when we encapsulate everything into class, we can get something like:

template <typename _Key, typename _Base, 
  typename _Predicator = std::less<_Key> >
class CClassFactory
    CClassFactory() {};
    ~CClassFactory() {};

    typedef _Base* (*CreatorFunction) (void);
    typedef std::map<_Key, CreatorFunction, _Predicator> _mapFactory;

    // called at the beginning of execution to register creation functions
    // used later to create class instances
    static _Key RegisterCreatorFunction(_Key idKey, 
                              CreatorFunction classCreator)
             CreatorFunction>(idKey, classCreator));
        return idKey;

    // tries to create instance based on the key
    // using creator function (if provided)
    static _Base* CreateInstance(_Key idKey)
        _mapFactory::iterator it = get_mapFactory()->find(idKey);
        if (it != get_mapFactory()->end())
            if (it->second)
                return it->second();
        return NULL;

    // map where the construction info is stored
    // to prevent inserting into map before initialisation takes place
    // place it into static function as static member, 
    // so it will be initialised only once - at first call
    static _mapFactory * get_mapFactory()
        static _mapFactory m_sMapFactory;
        return &m_sMapFactory;

So, Let's Sum It Up

Now, everything is prepared to be used. To do so, it is necessary:

  • Decide, what to use as a key (e.g., integer/string/GUID/pair of values) and define the corresponding predicate functor.
  • In class definition, add static "creator" function and dummy variable:
    static CSampleBase* SampleCreatorFunction() {return new CSampleOne;}
    static int iDummyNr;
  • To initialize dummy variable, call the code to register creator function:
    int CSampleOne::iDummyNr = CClassFactory<int, 
        CSampleBase >::RegisterCreatorFunction(1, 
  • And to create an object, just call:
    CSampleBase * pBase = CClassFactory<int, 
         CSampleBase >::CreateInstance(1);

Known Constraints

This class will work perfectly if you don't start to play with multiple threads. It is well known(?) that MS <map> itself doesn't play nicely in multithreading environment, so that would be the first place to watch... My solution was to protect all class calls by critical section, but it wasn't a generic solution so I won't include it here.

Also, the way it is presented here allows only one instance of class factory per combination of Key/Base/Predicator. Which is OK for most instances, but there might be cases when it isn't - then a new template parameter will help.


This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Web Developer
United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralTo get the code to compile on more recent versions of g++ Pin
rm_2517-Apr-09 5:49
memberrm_2517-Apr-09 5:49 
Questionregarding clean-up Pin
jayeshskul18-Nov-06 21:09
memberjayeshskul18-Nov-06 21:09 
AnswerRe: regarding clean-up Pin
mimicry19-Nov-06 13:04
membermimicry19-Nov-06 13:04 
QuestionRe: regarding clean-up Pin
jayeshskul23-Nov-06 7:16
memberjayeshskul23-Nov-06 7:16 
GeneralGood Job!! Pin
Member 44456820-Oct-05 20:43
memberMember 44456820-Oct-05 20:43 
GeneralBeware of using in static libraries Pin
7-ZARK-726-Jul-04 2:05
member7-ZARK-726-Jul-04 2:05 
GeneralRe: Beware of using in static libraries Pin
mimicry26-Jul-04 3:39
membermimicry26-Jul-04 3:39 
GeneralRe: Beware of using in static libraries Pin
7-ZARK-728-Jul-04 22:22
member7-ZARK-728-Jul-04 22:22 
GeneralRe: Beware of using in static libraries Pin
shaochen198029-Jul-04 4:49
membershaochen198029-Jul-04 4:49 
GeneralRe: Beware of using in static libraries Pin
7-ZARK-72-Aug-04 2:21
member7-ZARK-72-Aug-04 2:21 
GeneralRe: Beware of using in static libraries Pin
jhuang_sugarcane22-Nov-04 23:59
memberjhuang_sugarcane22-Nov-04 23:59 
GeneralAnd very similar to one of my examples Pin
Patje25-Jul-04 22:03
memberPatje25-Jul-04 22:03 
GeneralThis seems similar to the &quot;Abstract Factory&quot; design pattern from GoF. Pin
Don Clugston25-Jul-04 14:58
memberDon Clugston25-Jul-04 14:58 
GeneralRe: This seems similar to the &quot;Abstract Factory&quot; design pattern from GoF. Pin
mimicry26-Jul-04 0:41
membermimicry26-Jul-04 0:41 
GeneralRe: This seems similar to the &quot;Abstract Factory&quot; design pattern from GoF. Pin
John M. Drescher26-Jul-04 12:48
memberJohn M. Drescher26-Jul-04 12:48 

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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.190114.1 | Last Updated 18 Nov 2018
Article Copyright 2004 by mimicry
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid