Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在C+中实例化类+;从类类型作为std::map值_Java_C++_Reflection_Stl - Fatal编程技术网

Java 在C+中实例化类+;从类类型作为std::map值

Java 在C+中实例化类+;从类类型作为std::map值,java,c++,reflection,stl,Java,C++,Reflection,Stl,我需要将以下java概念移植到C++: 包含对象id键和类类型值的哈希映射: Map<String, Class> _objectsBank = new HashMap<>(); 然后,稍后,我构建了一个按需保存在该银行中的类的实例。 有点“懒惰”初始化: 我怎么用C++做?如何将类类型设置为std::map value,以便稍后查询它以从中构造适当的实例? Boost库中有类似的东西吗 一个选项是,您可以存储表示实例的字符串,而不是类名,然后使用工厂方法返回正确的实

我需要将以下java概念移植到C++:

包含对象id键和类类型值的哈希映射:

 Map<String, Class> _objectsBank = new HashMap<>();
然后,稍后,我构建了一个按需保存在该银行中的类的实例。 有点“懒惰”初始化:

<>我怎么用C++做?如何将类类型设置为std::map value,以便稍后查询它以从中构造适当的实例?
Boost库中有类似的东西吗

一个选项是,您可以存储表示实例的字符串,而不是类名,然后使用工厂方法返回正确的实例。但这将更为笨拙,因为您需要通过执行以下操作手动模拟反射过程

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]();
}
typedef MyClass*(*MyFactoryFunc)();
地图我的地图;
MyClass*createDerived1(){返回新的Derived1();}
...
MyClass*initNewProg(字符串名称){
返回myMap[name]();
}

如果使用Qt并将对象转换为QoObject是一种选择,那么它可以通过Qt元对象系统实现这一点。研究它的实际出发点是方法和文档

这也说明了,在C++中获得这样的特性或多或少需要额外的预处理步骤,例如QT的代码> MOC < /代码>,它创建额外的.CPP文件,并使用额外的方法和数据来支持这个。


一个更轻量级的选项可能是开发您自己的简单预处理器,例如,它读取.cpp文件中的一些特殊注释符号,并可能生成代码来创建映射,该映射将对象类型映射到实例化对象的函数,或其他。我不确定你是否可以哄骗C++模板系统来完成大部分的工作。

< p>你可以使用函数指针。 由于不能使用指向构造函数的函数指针,因此必须使用工厂函数:

template <class Derived>
Base* create()
{
        return new Derived;
}
模板
Base*create()
{
返回新导出的;
}
然后,您可以在映射中保存指向工厂函数模板实例的函数指针,以构造派生类:

int main()
{
        std::map<std::string, Base*(*)()> classMap;
        classMap["Derived1"] = &create<Derived1>;
        classMap["Derived2"] = &create<Derived2>;

        delete classMap["Derived1"]();
        delete classMap["Derived2"]();   
}
intmain()
{
std::map类映射;
classMap[“Derived1”]=&创建;
classMap[“Derived2”]=&创建;
删除类映射[“Derived1”]();
删除类映射[“Derived2”]();
}

参见

查看和,其中描述了问题和多种方法,以及每种方法的优缺点。示例包括注册类的构造函数,这解决了您在@Karthik T的解决方案中提到的多个if语句的问题。

C++没有反射,因此无法准确地执行此操作。我已经知道了,有任何可能的解决方法吗?:)通常,试图将一种习语从一种语言翻译成另一种语言会产生非常僵硬、无法维护的代码,即使这是完全可以做到的。修改这个问题也许会更好地显示大画面的目标,并要求作为一个纯粹的C++问题如何实现这个目标。为什么要投否决票?我只是没有找到那个复制品。这正是我想要避免的。想象一下,我有成百上千个这样的if()…否则要执行…@MichaelIV你可以,但如果可以重新设计,那可能会更好。由于检查对象类型的方法是执行
dynamic\u cast
并查看是否成功,因此幸运的是,您无法在此项目中使用Qt。添加了关于自己执行类似操作的段落。
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"]();   
}