Is there a way to instantiate objects from a string holding their class name?
我遇到的问题与上述问题基本相同。但是我需要用一些参数来实例化一个类。不同的类构造函数名称可能需要不同数量的变量,每个变量的类型也可能不同。并且因为该类包含常量变量,所以您无法使用新的T()新建它,然后将参数设置为正确的值。 “类名” - “构造函数”地图似乎不适合我的需要。
任何替代方案?
答案 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