繁体   English   中英

将C ++中的类从类类型实例化为std :: map值

[英]Instantiate class in C++ from class type as std::map value

我需要将以下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库中是否有类似的东西?

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

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看到

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

一种选择是,您可以存储代表实例的字符串,而不用类名,然后再使用工厂方法返回正确的实例。 但这会比较麻烦,因为您需要通过执行以下操作来手动模拟反射过程。

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

如果使用Qt并将对象放入QObjects是一种选择,则可以通过Qt元对象系统来实现。 实用的起点是QObject::metaObject()QMetaObject::newInstance()方法文档。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM