0

我需要将以下 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库中有这样的东西吗?

4

4 回答 4

5

您可以使用函数指针。由于您不能将函数指针指向构造函数,因此必须使用工厂函数:

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"]();   
}

Ideone上看到

于 2013-01-27T15:26:08.210 回答
3

看看有没有办法从保存类名的字符串中实例化对象?以及使用工厂模式按名称实例化类,它描述了问题和多种方法以及每种方法的优缺点。这些示例涵盖了类的构造函数注册,这解决了您在@Karthik T 的解决方案中提到的多个 if 语句的问题。

于 2013-01-27T15:33:51.987 回答
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]();
}
于 2013-01-27T14:31:33.147 回答
0

如果使用 Qt 并将你的对象变成 QObjects 是一种选择,那么它可以通过 Qt 元对象系统来做到这一点。QObject::metaObject()研究它的实际起点是QMetaObject::newInstance()方法文档。

这也说明了这一点,在 C++ 中获得这样的功能或多或少需要额外的预处理步骤,例如 Qt's moc,它创建额外的 .cpp 文件,其中包含额外的方法和数据来支持这一点。

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

于 2013-01-27T14:38:56.677 回答