带模板参数的std :: vector

时间:2016-08-06 16:57:36

标签: c++ templates vector stl stdvector

我得到了这样的代码:

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方法中执行此操作。是否可以保存有关要在向量中实例化的类的信息,或者将在整个Engine类中共享的任何其他数据结构,所以我可以稍后在其他方法中调用它?我想要实现的伪代码:

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

1 个答案:

答案 0 :(得分:1)

您要创建的类型是否具有共同基础? 与在C ++中一样,您不能拥有不相关类型的集合(向量/映射),类型应该有一个公共基类,以便以下代码工作。 (否则,您可以使用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;

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

它们都从CreatorBase继承,因此它们可以存储在地图中。

创建者返回Entity *,对于类型安全,我们可以在调用create()时使用动态强制转换,以确保我们创建正确的类型。

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

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