By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,474 Members | 3,141 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,474 IT Pros & Developers. It's quick & easy.

Class object factories, references to a **class**

P: n/a
I am trying to create a way to register static members of a **class**, not
an object, for making an object factory. The main thing I want is to be
able to make a call like

class MyClass
{
public:
MyClass *factory();
};
register(MyClass);

and have a method that calls MyClass::factory() to return a MyClass object
on a call like 'MyClass *o = create("MyClass");'.

Is there any C++ construct that would allow this sort of class registration?
I'd be into using macros and even templates (hopefully not).
Here is a longer example...

main.cpp:
------------------------------------------
#include <map>
#include <typeinfo>

typedef std::map<const char *, void (something::*)()> FactoryMap;

FactoryMap *getMap()
{
// I need there to be exactly one instance of registry.
static FactoryMap registry;
return &registry;
}

int register(something Class)
{
pair<const char *, void (something::*)()> p(typeid(Class).name(),
Class::factory);

getMap()->insert(p);
}

void *create(const char *classname)
{
FactoryMap::iterator it = getMap()->find(classname);
if(it != getMap()->end())
return it->second();
else
return NULL;
}

class A
{
public:
static A *factory(){return new A;}
};
int aDummy = register(A); // THIS IS THE SORT OF CALL I'M AFTER
class B : public A
{
public:
static A *factory(){return new B;}
};
int bDummy = register(B); // AGAIN, THIS IS THE SORT OF CALL I'M AFTER

int main()
{
A *a = *b
}

Jul 22 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a

"Patrick Stinson" <aj*****@gci.net> wrote in message
news:10*************@corp.supernews.com...
I am trying to create a way to register static members of a **class**, not
an object, for making an object factory. The main thing I want is to be
able to make a call like

class MyClass
{
public:
MyClass *factory();
};
register(MyClass);

and have a method that calls MyClass::factory() to return a MyClass object
on a call like 'MyClass *o = create("MyClass");'.

Is there any C++ construct that would allow this sort of class registration? I'd be into using macros and even templates (hopefully not).
Here is a longer example...

main.cpp:
------------------------------------------
#include <map>
#include <typeinfo>

typedef std::map<const char *, void (something::*)()> FactoryMap;

FactoryMap *getMap()
{
// I need there to be exactly one instance of registry.
static FactoryMap registry;
return &registry;
}

int register(something Class)
{
pair<const char *, void (something::*)()> p(typeid(Class).name(),
Class::factory);

getMap()->insert(p);
}

void *create(const char *classname)
{
FactoryMap::iterator it = getMap()->find(classname);
if(it != getMap()->end())
return it->second();
else
return NULL;
}

class A
{
public:
static A *factory(){return new A;}
};
int aDummy = register(A); // THIS IS THE SORT OF CALL I'M AFTER
class B : public A
{
public:
static A *factory(){return new B;}
};
int bDummy = register(B); // AGAIN, THIS IS THE SORT OF CALL I'M AFTER

int main()
{
A *a = *b
}


Patrick,

here's an outline of a solution - basically I've used templates to make
factory objects out of
your classes so I can call their static methods through a virtual function.
The registration
process creates a mapping of factory to name, so you can do
factory.create("foobar").

dave

#include <stdio.h>
#include <string>
#include <map>
using namespace std;

class MyClass
{
public:
virtual void dofoo()=0;
};

class ClassFactory
{
public:
virtual MyClass* create()=0;
virtual string name()=0;

};
template < class T >
class FactoryWrapper : public ClassFactory
{
public:
virtual MyClass* create(){ return T::create();}
virtual string name(){ return T::name();}
};

class Factories
{
public:
void registerFactory( ClassFactory* factory)
{
_facts[factory->name()]=factory;
}
MyClass* create( const string& name)
{
if ( _facts[name] )
{
return _facts[name]->create();
}

return 0;
}
map<string, ClassFactory*> _facts;

};
class Class1 : public MyClass
{
public:
static Class1* create(){ return new Class1();};
virtual void dofoo(){ printf("Class1::dofoo\n");};
static string name(){ return "Class1";} ;

};
class Class2 : public MyClass
{
public:
static Class2* create(){ return new Class2();};
virtual void dofoo(){ printf("Class2::dofoo\n");};
static string name(){ return "Class2";} ;

};

int main(int argc, char* argv[])
{
FactoryWrapper<Class1> class1Factory;
FactoryWrapper<Class2> class2Factory;
Factories factories;

factories.registerFactory(&class1Factory);
factories.registerFactory(&class2Factory);

MyClass* c1= factories.create("Class1");
MyClass* c2= factories.create("Class2");
c1->dofoo();
c2->dofoo();

return 0;
}

Jul 22 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.