我需要将以下Java概念移植到C ++中:
包含对象id键和类类型值的哈希映射:
Map<String, Class> _objectsBank = new HashMap<>();
在init方法的某处,我像这样填写银行:
_objectsBank .put("CLASS_ID_1", MyClass1.class);
_objectsBank .put("CLASS_ID_2", MyClass2.class);
....
然后,我按需要构建一个保存在该库中的类的实例。 一种“懒惰”的初始化:
private MyClass initNewProg(String name) {
MyClass instance;
try {
Class cl = _objectsBank.get(name);
java.lang.reflect.Constructor co = cl.getConstructor(String.class);
instance= (MyClass) co.newInstance(name);
return instance;
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
e.printStackTrace();
return null;
}
}
我如何在C ++中完成它?如何将类类型设置为std :: map值,以便稍后可以查询它以从中构造适当的实例? 在Boost库中有这样的东西吗?
答案 0 :(得分:4)
您可以使用函数指针。 由于您无法使用指向构造函数的函数指针,因此必须使用工厂函数:
template <class Derived>
Base* create()
{
return new Derived;
}
然后,您可以将函数指针保存到地图中工厂函数的模板实例,以构建派生类:
int main()
{
std::map<std::string, Base*(*)()> classMap;
classMap["Derived1"] = &create<Derived1>;
classMap["Derived2"] = &create<Derived2>;
delete classMap["Derived1"]();
delete classMap["Derived2"]();
}
上查看
答案 1 :(得分:3)
查看Is there a way to instantiate objects from a string holding their class name? 和Instantiating classes by name with factory pattern,其中介绍了问题以及与专业人士合作的多种方法。每个人的利弊。这些示例包括类的构造函数的注册,这解决了您在@Karthik T的解决方案中提到的多个if语句的问题。
答案 2 :(得分:1)
一个选项是,您可以存储表示实例的字符串,然后使用工厂方法返回正确的实例,而不是类名。但这将是笨拙的,因为您需要通过执行以下手动模拟反射过程。
MyClass* initNewProg(string name) {
if(name == "derived1")
return new Derived1();
else if(name == "derived2")
....
}
另一种方法是使用单独的工厂方法和函数指针。
typedef MyClass* (*MyFactoryFunc)();
map<string,MyFactoryFunc> myMap;
MyClass* createDerived1(){return new Derived1();}
...
MyClass* initNewProg(string name) {
return myMap[name]();
}
答案 3 :(得分:0)
如果使用Qt并将对象放入QObjects是一个选项,那么它可以通过Qt元对象系统完成。查看它的实际出发点是QObject::metaObject()
和QMetaObject::newInstance()
方法文档。
这也说明了这一点,即在C ++中获得这样的功能或多或少需要额外的预处理步骤,例如Qt的moc
,它会创建额外的.cpp文件以及支持此功能的额外方法和数据。
更轻量级的选项可能是开发自己的简单预处理器,例如在.cpp文件中读取一些特殊的注释符号,并且可能生成用于创建映射的代码,该映射将对象类型映射到实例化对象的函数, 或者其他的东西。我不确定你是否可以哄骗C ++模板系统为你完成大部分工作。