首页 > 后端开发 > C++ > 如何从包含类名的字符串创建 C 对象?

如何从包含类名的字符串创建 C 对象?

Patricia Arquette
发布: 2024-12-20 01:33:10
原创
1015 人浏览过

How to Create C   Objects from a String Containing Their Class Name?

如何从包含类名的字符串实例化对象?

在给定的代码中,BaseFactory 类创建不同派生类的对象基于代表其类名的字符串。但是,工厂需要为每个可能的派生类手动添加 if 语句。人们可能想知道是否有一种替代这种冗长方法的方法,类似于 C# 的反射功能。

不幸的是没有自动化机制

不幸的是,C 没有机制用于自动创建运行时指定类型的对象。但是,您可以自己进行映射:

类型映射

您可以创建一个映射,为每个类名存储一个创建对象的函数该类的:

template<typename T> Base * createInstance() { return new T; }

typedef std::map<std::string, Base*(*)()> map_type;

map_type map;
map["DerivedA"] = &amp;createInstance<DerivedA>;
map["DerivedB"] = &amp;createInstance<DerivedB>;
登录后复制

然后你也可以实例化对象help:

return map[some_string]();
登录后复制

类型注册

另一种解决方案是允许类型自行注册:

// w base.hpp:
template<typename T> Base * createT() { return new T; }

struct BaseFactory {
    typedef std::map<std::string, Base*(*)()> map_type;

    static Base * createInstance(std::string const&amp; s) {
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
            return 0;
        return it->second();
    }

protected:
    static map_type * getMap() {
        // nigdy nie usuwane (istnieje do zakończenia programu)
        // ponieważ nie możemy zagwarantować poprawnej kolejności usuwania
        if(!map) { map = new map_type; }
        return map;
    }

private:
    static map_type * map;
};

template<typename T>
struct DerivedRegister : BaseFactory {
    DerivedRegister(std::string const&amp; s) {
        getMap()->insert(std::make_pair(s, &amp;createT<T>));
    }
};

// w derivedb.hpp
class DerivedB {
    ...;
private:
    static DerivedRegister<DerivedB> reg;
};

// w derivedb.cpp:
DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
登录后复制

您还可以定义宏对于类型注册:

#define REGISTER_DEC_TYPE(NAME) \
    static DerivedRegister<NAME> reg

#define REGISTER_DEF_TYPE(NAME) \
    DerivedRegister<NAME> NAME::reg(#NAME)
登录后复制

对于不共享公共基类的类型,您可以使用变体boost::variant 作为函数的返回类型:

typedef boost::variant<Foo, Bar, Baz> variant_type;
template<typename T> variant_type createInstance() {
    return variant_type(T());
}

typedef std::map<std::string, variant_type (*)()> map_type;
登录后复制

以上是如何从包含类名的字符串创建 C 对象?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板