基于字符串输入创建类实例

时间:2013-10-06 21:05:14

标签: c++ sdl sdl-2

背景:

在我的游戏引擎中,我有一个通用的“脚本解析器”,用于通过解析脚本文件来创建游戏实体。因此,在代码中,您会有类似MyEntity* entity = MyScriptParer::Parse("filename.scr");

的内容

任何可编写脚本的类都继承自通用基类。在游戏引擎的内部,有一些特定的类使用它 - 粒子,字体等,这一切都在解析器中很好地工作 - 参见下面的摘录

std::string line;
std::getline(ifs, line);

if (line == "[FONT]") {
    CFont* f = new CFont();
    f->readObject(ifs);
}
else if (line == "[PARTICLE]") {
    CParticle* p = new CParticle();
    p->readObject(ifs);
}
...

我的问题在于如何处理用户定义的类,即使用游戏引擎的游戏中的类。基类有一个抽象方法readObject,因此任何继承的方法都必须实现此方法。

问题是解析器如何知道新类?例如,我有一个CVehicle类,解析器现在需要知道识别“[VEHICLE]”并且还能够创建new CVehicle

有没有办法在数组/映射中存储类类型或类似的东西,所以也许我可以有一个函数来用字符串注册类类型列表来提供创建新实例的查找?

有点远,可能不可能,所以如果有人对如何接近解析提出其他建议,他们将受到欢迎

2 个答案:

答案 0 :(得分:1)

可以通过std::type_info

在数组/地图中存储类类型

但是,您无法从中创建类型,因为它需要比C ++中更多的RTTI。 (比如.NET中的反射)。

但是,您可以在此类地图中存储指向类工厂的函数指针。 即。

typedef CBaseClass* (*pfnCreateClass)();

std::map<std::string, pfnCreateClass> mapCreate;

// Registering
// CMyCustomClass::GetClass() is a static method that creates a CMyCustomClass
mapCreate.insert(std::pair<std::string, pfnCreateClass>("[CUSTOM_CLASS]", CMyCustomClass::GetClass));

// Get class
std::map<std::string, pfnCreateClass>::const_iterator it = mapCreate.find(line);
if(mapCreate.end() != it)
{
    CBaseClass *p = it->second();
    p->readObject(ifs);
}

答案 1 :(得分:0)

只需拥有注册新类型的功能,可以使用类型名称和创建类型的函数。

像这样:

void RegisterType( std::string name, std::function< BaseType() > createFunc );

注册新类型时,您可以这样做:

RegisterType( "Vehicle", [](){ return new CVehicle; } );

这样解析器就可以创建所有派生类型。