如何只知道其名称来实例化对象?

时间:2011-11-25 12:56:58

标签: c++ class reflection instantiation

  

可能重复:
  Is there a way to instantiate objects from a string holding their class name?

在C ++中,我想让我的用户输入要在运行时创建的对象类型名称,并且,根据我从中获取的字符串,程序将实例化正确的对象(简而言之,我是实现工厂方法模式)。但是,如果程序必须支持新的对象类型,则不允许修改现有代码。

因此可以从方法中删除所有if ... else if ... else if ...并且仍然让我的程序实例化特定产品类型的正确对象(多个,其中只在编译时才知道?

我的搜索给了我这个链接:Is there a way to instantiate objects from a string holding their class name? 它似乎就是我想要的但我根本无法理解代码。

任何帮助都会非常感激。

2 个答案:

答案 0 :(得分:5)

这仅在所有必需类派生自某个公共基类时才有效,并且通常仅限于使用基本接口(尽管您可以通过一些额外的工作来解决这个问题)。这是一种方法:

// Immutable core code:

#include <map>
#include <string>

class Base
{
  typedef Base * (*crfnptr)(const std::string &);
  typedef std::map<std::string, crfnptr> CreatorMap;

  static CreatorMap creators;

public:
  virtual ~Base() { }
  Base * clone() const { return new Base(*this); }

  static Base * create_from_string(std::string name)
  {
    CreatorMap::const_iterator it = creators.find(name);
    return it == creators.end() ? NULL : it->first();
  }

  static void register(std::string name, crfnptr f)
  {
    creators[name] = f;
  }
};

现在您可以从新代码中添加新的派生类:

// your code:

#include "immutable_core.hpp"

class Foo : public Base
{
public:
  Foo * clone() const { return new Foo(*this); }
  static Foo * create() { return new Foo; }
};

Base::register("Foo", &Foo::create);

要创建课程,只需致电Base * p = Base::create_from_string("Foo");

答案 1 :(得分:2)

你可以实现像插件系统这样的实现。我在Linux中使用dlopen实现了这一点。该程序不需要修改,但您只需要添加新类作为将在运行时加载的动态库。

您可以从此处开始了解详情:C++ dlopen mini HOWTO