我得到了这样的代码:
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;
}
答案 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