代码之家  ›  专栏  ›  技术社区  ›  solusipse

带有模板参数的std::vector

  •  -2
  • solusipse  · 技术社区  · 9 年前

    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 回复  |  直到 9 年前
        1
  •  1
  •   Nuclear    9 年前

    您将创建的类型是否具有公共基础? 正如在C++中不能有无关类型的集合(vector/map)一样,类型应该有一个公共基类,以便下面的代码工作。(否则,可以使用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;
    

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

    它们都继承自Creator Base,因此可以存储在地图中。

    创建者返回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
    
    推荐文章