Reputation: 305
I am writing a generic factory class called Factory
//abstract factory
template <class C>
class Factory{
public:
virtual C* create()=0;
}
//concrete factory
template <class C>
class NormalFactory:public Factory<C>{
public:
C* create(){return new C;}
}
I want to do the following:
typedef Factory<Enemy> EnemyFactory;
EnemyFactory* e = new NormalFactory<Troll>; //Troll inherits Enemy
//client code
Enemy* enemy = e->create();
But unfortunately I can't do that since NormalFactory does not inherit Factory. Is there a way around that to accomplish what I wanted to?
(implementing an abstracted EnemyFactory without knowing the actual type of Enemy
it create()
)
Upvotes: 0
Views: 151
Reputation: 19761
You can templatize create so that you say what type of enemy it will create.
template<class T>
T * create() {
return new T;
}
Enemy * e = my_normal_factory.create<Troll>();
In which case there's no need to templatize the class.
or this
//abstract factory
class Factory{
public:
virtual Enemy * create()=0;
}
//concrete factory
template <class C>
class NormalFactory:public Factory<C>{
public:
Enemy* create(){return new C;}
}
Factory* e = new NormalFactory<Troll>; //Troll inherits Enemy
void some_function(Factory & somefactory) {
Enemy* enemy = somefactory->create();
}
some_function(e);
Upvotes: 0
Reputation: 145279
A simple technical solution is to parameterise the concrete factory with the desired base, like this:
template <class C, class C_base = C>
class NormalFactory:public Factory<C_base>{
public:
C* create(){return new C;}
};
However, the design doesn't feel right somehow. I suggest thinking about what the factories are meant to accomplish, and if there's any other more natural way of accomplishing that in C++. I.e., I think this is an XY-question.
Upvotes: 1