如何实例化构造函数需要包含类名的字符串参数的对象?

时间:2011-10-07 14:33:27

标签: c++ reflection instantiation

Is there a way to instantiate objects from a string holding their class name?

我遇到的问题与上述问题基本相同。但是我需要用一些参数来实例化一个类。不同的类构造函数名称可能需要不同数量的变量,每个变量的类型也可能不同。并且因为该类包含常量变量,所以您无法使用新的T()新建它,然后将参数设置为正确的值。 “类名” - “构造函数”地图似乎不适合我的需要。

任何替代方案?

2 个答案:

答案 0 :(得分:1)

我将在前言中说,也许C ++不适合你想要完成的任何事情。您尝试通过外部数据控制程序越多,就越接近完全编写脚本。当这是你的目标时,有很多更强大的选择。

那说,当然,这是可能的,虽然不是那么容易。有两种方法可以立刻想到。第一个是要求所有适用的类型都有一个接受std::string的构造函数。该构造函数将负责自己的解析。

template<typename T> Base * createInstance(const std::string& s) { return new T(s); }
typedef std::map<std::string, Base*(*)(const std::string&)> map_type;
//...and similar changes as needed

如果您不想更改类型定义,或者这是不可接受的[也许您的类型已经有这样的构造函数?],请删除模板createInstance方法,并为每个类型提供单独的版本您感兴趣的类型。此函数执行解析,并调用适当的构造函数。

map["derivedA"] = createDerivedA;
map["derivedB"] = createDerivedB;

第三个选项可能可以使用可变参数模板[或类似于增强型变量模板的模板],这将使您恢复原始的简单性。

template<typename T, typename... Args>
Base* create(std::string) {
  //somehow pass the string to a generic function that packs the arguments into a tuple
  //then somehow unpack that tuple and pass the bits to the constructor
}

map["derivedA"] = create<derivedA, int, double, std::string>;

但是,我不知道如何解决这个问题,即使有可能。

答案 1 :(得分:0)

您可以使用工厂设计图案。将您的字符串传递给工厂类,然后让它解码您的字符串,选择要调用的构造函数和类的正确版本。然后它将传回一个正确类的实例,以供您使用的其余代码。 这是一些信息factory design pattern