std::vector 带有模板参数

std::vector with a template argument

我得到了这样的代码:

template<class T> void Engine::extend( std::string name ) {
    T *instance = new T( this );
    this->newExtensions[name] = instance;
}

这样称呼:

engine.extend<Menu>( "menu" );

它工作得很好,但我想稍后在我的代码中(在我的游戏的主循环中)创建一个 T 的新实例,而不是在 Engine::extend 方法中这样做.是否可以保留有关 class 的信息以向量或任何其他将在整个 Engine class 中共享的数据结构进行实例化,以便我稍后可以在其他方法中调用它?我想要实现的伪代码:

template<class T> void Engine::extend( std::string name ) {
    this->newExtensions[name] = T;
}

您要创建的类型是否有共同的基础? 与在 C++ 中一样,您不能拥有不相关类型的集合(向量/映射),类型应该有一个公共基础 class 才能使以下代码正常工作。 (否则,您可以使用 void*,但转换将不安全):

#include <iostream>
#include <map>

class Entity {
    public:
    virtual ~Entity(){}
};

class C1: public Entity
{
    public:
    void doSomething(){std::cout << "C1" << std::endl;}
};

class C2: public Entity
{
    public:
    void doSomething(){std::cout << "C2" << std::endl;}
};

class C3
{
    public:
    void doSomething(){std::cout << "C3" << std::endl;}
};



class CreatorBase {
    public:
        virtual ~CreatorBase () {};
        virtual Entity* create () = 0;  
};

template<typename T>
class Creator: public CreatorBase {
    public:
        Entity* create ()
        {
            return new T;
        }       
};

std::map<int, CreatorBase*> cmap;

在这里,我们有一个基础实体 class,C1 和 C2 继承自它。 接下来是模板classCreator,它创建一个请求类型的对象。

都是继承自CreatorBase,所以可以存储在一个map中。

创建者 returns 实体*,为了类型安全,我们可以在调用 create() 时使用动态转换,以确保我们正在创建正确的类型。

如果你只需要一个实体指针,你可以在任何地方使用实体*,不需要动态转换。

int main(int argc, char *argv[])
{   
    cmap[1]=new Creator<C1>;
    cmap[2]=new Creator<C2>;
    //cmap[3]=new Creator<C3>;  //will not compile - C3 does not derive from Entity

    C1 *i1 = dynamic_cast<C1*> (cmap[1]->create());  
    C2 *i2 = dynamic_cast<C2*> (cmap[2]->create());
    C1 *i3 = dynamic_cast<C1*> (cmap[2]->create()); //bad dynamic cast: cmap[2] does not create C1

    if (!i1) {
        std::cout << "i1: Bad dynamic cast" << std::endl;
    } else {    
        i1->doSomething();
    }

    if (!i2) {
        std::cout << "i2: Bad dynamic cast" << std::endl;
    } else {    
        i2->doSomething();
    }   

     if (!i3) {
        std::cout << "i3: Bad dynamic cast" << std::endl;
    } else {
            i3->doSomething();
    }
}

输出:

C1
C2
i3: Bad dynamic cast