Hi all,
I have an interesting problem for which I already have a solution, but I have a feeling my solution is less than elegant.
I need to create a Factory class which returns an instance of some child of class Foo. Which child is instantiated depends on the value of some integer parameter. So, for example, the following would work well enough:
class FooFactory
{
public:
Foo* getFooInstance( int id );
}
Foo* FooFactory::getFooInstance( int id )
{
switch (id) {
case 1:
return new FooBar();
case 2:
return new FooBoo();
default:
return NULL;
}
}
However, I would need to maintain that switch statement everytime I implement a child class of Foo. So, a better solution, I feel, is to register the child class during static initialization:
// FooFactory.h
class FooFactory
{
typedef Foo* (*FooInstantiator)();
typedef std::map<int, FooInstantiator> InstantiatorMap;
public:
Foo* getFooInstance( int id );
static int registerFooInstantiator(int id, FooInstantiator func);
private:
static InstantiatorMap m_instantiatorMap;
}
// FooFactory.cpp
// For the sake of brevity, let's just assume we've guaranteed that
// m_instantiatorMap already has been constructed.
int FooFactory::registerFooInstantiator(int id, FooInstantiator func)
{
m_instantiatorMap.insert( std::make_pair( id, func ) );
return 1;
}
// FooBar.h
class FooBar : public Foo
{
...
static int isInitialized;
...
}
Foo* getFooBar();
// FooBar.cpp
int FooBar::isInitialized =
FooFactory::registerFooInstantiator( 1, getFooBar );
Foo* getFooBar() { return new FooBar(); }
The above solution allows me to create a new Foo child class and add it to the factory without having to modify the factory code.
Can I do better? Having to create a getFooXXX() function for each child seems unnecessary. I was thinking of creating a template function getFoo<T>, declared in FooFactory.h, where T would be the child class. This removes the need for separate getFooXXX functions. Any thoughts?