c ++模板协方差多态性

时间:2016-01-02 01:30:27

标签: c++ templates polymorphism

我正在编写一个名为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;}
}

我想做以下事情:

typedef Factory<Enemy> EnemyFactory;
EnemyFactory* e = new NormalFactory<Troll>; //Troll inherits Enemy
//client code
Enemy* enemy = e->create();

但遗憾的是我不能这样做,因为NormalFactory不会继承Factory。有没有办法实现我想要的目标?

(在不知道Enemy create()的实际类型的情况下实现抽象的EnemyFactory

2 个答案:

答案 0 :(得分:1)

一个简单的技术解决方案是使具有所需基数的具体工厂参数化,如下所示:

template <class C, class C_base = C>
class NormalFactory:public Factory<C_base>{
    public:

    C* create(){return new C;}
};

Example at Coliru

然而,设计并不以某种方式感觉正确。我建议考虑工厂要完成什么,以及是否还有其他更自然的方法来实现C ++。即,我认为这是一个XY-question

答案 1 :(得分:0)

你可以模仿创造,以便你说出它会创造什么类型的敌人。

template<class T>
T * create() {
    return new T;
}

Enemy * e = my_normal_factory.create<Troll>();

在这种情况下,没有必要对课程进行模板化。

或者

//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);