是否可以在c ++中使用传递的类型名称(字符串)返回对象的示例?
我有一些基本的抽象类Base
和一些派生。示例代码:
class Base
{
/* ... */
};
class Der1 : public Base
{
/* ... */
};
class Der2 : public Base
{
/* ... */
};
我需要以下功能:
Base *objectByType(const std::string &name);
派生类的数量是可变的,我不想做像name
的切换和手动返回新对象类型。是否有可能在c ++中自动执行此操作?
P.S。用法应如下:
dynamic_cast<Der1>(objectByType("Der1"));
我需要纯c ++代码(跨平台)。允许使用提升。
答案 0 :(得分:2)
在C ++中无法做到这一点。
一个选项是写一个工厂并打开传入的名称,但我发现你不想这样做。除了dynamic_cast之外,C ++不提供任何真正的运行时反射支持,因此这类问题很难解决。
答案 1 :(得分:2)
有一个很好的技巧,可以让你编写一个factory method而不需要if...else if...
的序列。
(请注意,AFAIK,确实不可能在C ++中执行您想要的操作,因为此代码是在编译时生成的。为此目的存在“工厂方法”Design Pattern)
首先,为派生类定义global repository
。它可以采用std::map<std::string, Base*>
的形式,即将派生类的名称映射到该类的an instance
。
对于每个派生类,您定义一个default constructor
,它将该类的对象添加到类名下的存储库中。您还可以定义类的静态实例:
// file: der1.h
#include "repository.h"
class Der1: public Base {
public:
Der1() { repository[std::string("Der1")] = this; }
};
// file: der1.cpp
static Der1 der1Initializer;
静态变量的构造函数甚至在main()
之前运行,因此当您的main
启动时,您已经使用所有派生类的实例初始化了存储库。
您的工厂方法(例如Base::getObject(const std::string&)
)需要在存储库映射中搜索类名。然后,它使用它找到的对象的clone()
方法来获取相同类型的新对象。您当然需要为每个子类实现clone
。
这种方法的优点是,当您添加新的派生类时,您的添加仅限于实现新类的文件。存储库和工厂代码不会更改。当然,您仍需要重新编译程序。
答案 2 :(得分:0)
是的,这是可能的!检查一个名为Activator
的非常有趣的课程
您可以按Type
和string
创建所有内容,甚至可以提供参数列表,因此该方法将使用最佳参数集调用相应的构造函数。
答案 3 :(得分:0)
除非我误解,否则typeid
关键字应该是您要查找的内容的一部分。
答案 4 :(得分:0)
这是不可能的。您必须自己编写objectByType
函数:
Base* objectByType(const std::string& name) {
if (name == "Der1")
return new Der1;
else if (name == "Der2")
return new Der2;
// other possible tests
throw std::invalid_argument("Unknown type name " + name);
}
答案 5 :(得分:0)