c++ - 从 String 到 Type (C++) 的最佳方法是什么

标签 c++ types rtti

我希望能够将类型指定为字符串并在 C++ 中创建该类型。我知道 C++ 不直接支持这一点,但是解决这个问题的最佳方法是什么?

我当前有一个包含信息的 xml,但我想扩展它以包含组件。

<entity>
   <component>ComponentA</component>
   <component>ComponentB</component>
</entity>

我有一个通用工厂,它接受这些 xml 并构建实体。我希望能够避免 if("componentA") { new ComponentA; } 支持更通用的东西。主要是因为组件将由客户端定义,而工厂则不是。

我认为组件可以向工厂注册并存储 map ,但这需要保留我想避免的所有组件的拷贝。

我更喜欢跨平台解决方案。

最佳答案

据我所知,至少对于一般的 C++,没有隐式的方法来仅使用字符串创建类。然而,我过去使用过另一种机制。

首先,定义组件的概念:

class Component /* or IComponent if you're feeling adventurous - we may not have interfaces in C++, but dammit we like 'em! */
{
protected:
    Component() { };

public:
    virtual ~Component() = 0 { };
}; // eo class Component

以及某种创造者的概念:

class ComponentCreator
{
protected:
    Component() { };

public:
    virtual ~ComponentCreator() = 0 { };
    virtual Component* create() const = 0;  // Might want to use smart-pointers here - this is for illustrative purposes only.
}; // eo class ComponentCreator

好的,我们已经有了基础知识,现在我们需要一个可以让这些创建者注册的工厂:

class Factory
{
private:
    std::map<std::string, ComponentCreator*> _creators;

public:
    Factory() : _creators(new std::map<std::string, ComponentCreator*>();
    {
    };

    ~Factory()
    {
       // cleanup of _creators ommited.
    };

    // call to register a creator
    void register(const std::string& name, ComponentCreator* creator)
    {
        // normally you'd put checks to see if it exists etc.
        _creators[name] = creator;
    }; // eo register


    // call to create an instance
    Component* create(const std::string& name)
    {
        std::map<std::string, ComponentCreator*>::const_iterator cit(_creators.find(name));
        if(cit != _creators.end())
            return cit->create();
        else
            return NULL; // or nullptr
    }; // eo create
}; // eo class Factory

这样声明你的类(我只做一个):

class ComponentA : public Component { /* implementation */ };

不要忘记创造者:

class ComponentCreatorForA : public ComponentCreator
{
public:
    virtual Component* create() const { return new ComponentA(); };
}; // eo class ComponentCreatorForA

在程序初始化期间,您注册组件创建者:

factory.register("componentA", new ComponentCreatorForA());
factory.register("componentB", new ComponentCreatorForB());

稍后,我们可以按名称创建组件:

Component* component = factory.create("componentA");

注释:

  • 此方法假设组件在编译时已知。如果没有的话,可以引入一种插件架构,以便其他 DLL 可以在启动时通过工厂注册其组件,这样您就可以使其可扩展,而无需重新部署所有内容。

  • 在现实世界中,我们会使用一些此类的智能指针,并且 typedef 会去掉很多这样的东西,以便于打字!

关于c++ - 从 String 到 Type (C++) 的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20119509/

相关文章:

C++ 静态函数 : Put Inside or Outside Scope of Class?

c++ - 快速修复 C++ : Errors when compiling Acceptor

c++ - `type_info::before` 有什么用?

c++ - C++ 的自定义运行时类型系统/库

c++ - 覆盖文件中的字节而不清除它

c++ - 并行运行 CUDA 和 OpenGL,无需使用互操作性

java - 如何将 "dynamically"对象类型的实例转换为其特定数据类型?

delphi - 使用默认值时,rtti 不调用所需的重载函数

python - numpy.int64 乘以 int -> numpy.float64

list - OCaml:可以包含两种类型的列表?