在编译时生成某种子类/类型注册表?
Generating some sort of subclass / type registry at compile-time?
我正在编写一个应用程序(游戏(,其中包含父类的多个子类,这些子类都需要在映射中注册,以便可以在运行时读取的文件中引用它们。
例如,如果我有一个Subclass
类,并且我的文件指定它需要一个"Subclass"
的实例,我的文件解析器将在此映射中查找该值,这是一个初始化子类实例并将其作为父类指针返回的std::function
。
我目前从一个registry.cpp
文件中完成此操作,我必须手动输入每个新类,如下所示:
void register_all ()
{
registry["Subclass1"] = [] () { return new Subclass1 (); };
registry["Subclass2"] = [] () { return new Subclass2 (); };
// ... etc
}
我注意到其他具有类似设置的应用程序似乎能够使用宏自动注册这些子类(例如 Valve Software 的源引擎,它在类的 cpp 文件中使用DECLARE_CLASS宏,不需要头文件或任何其他配置。
如何在我自己的应用程序中完成这种零配置的"子类注册表"?
这些宏基本上声明了一个文件范围变量(在标识符中包含类名以使它们唯一(。此变量的构造函数调用函数来注册 lambda。
例如。像这样:
std::map<std::string, std::function<Parent*()>> actions;
class RegisterClass
{
public:
RegisterClass(std::string const& className, std::function<Parent*()>&& action)
{
actions.insert(std::make_pair(className, std::move(action)));
}
};
#define REGISTERCLASS(Class)
static RegisterClass tmpMyUniqueName ## Class( # Class, [](){return new Class;})
// ^ Single # quotes the identifier
// ^^ Double ## combines the pre and post identifiers.
如果您将上述方法用于:
class X: public Parent {};
class Y: public Parent {};
REGISTERCLASS(X);
REGISTERCLASS(Y);
您将获得:
class X: public Parent {};
class Y: public Parent {};
static RegisterClass tmpMyUniqueNameX( "X", [](){return new X;});
static RegisterClass tmpMyUniqueNameY( "Y", [](){return new Y;});
当前实现的支持基本上是您想要的方法。您有一个 id 字符串到默认构造函数的映射。这可以模板化以使语法更好(请参阅此出色的答案 http://stackoverflow.com/a/1809715/571778(
一旦有了它,您就可以在某处保留此注册映射的static
副本,然后编写一个宏来进行注册。这就是权衡。在我正在开发的游戏中,我根据加载编辑器还是普通游戏引擎来实例化不同的实现,因此能够在运行时替换不同的注册比静态注册在我的用例中是一个优势。
相关文章:
- C ++类型特征:确保子类实现方法
- 文本冒险游戏 - 如何区分一种项目类型与另一种项目类型以及如何构建项目类/子类
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- 附加类型安全的子类std::string
- 将方法参数类型更改为子类中的派生类
- 将子类实例保存在父类型变量中并通过父变量使用 Child 函数?
- 在子类上调用模板化静态方法时获取类的类型名
- 使用子类中的类型定义扩展模板类
- 当函数返回类型为父类时,如何返回子类的对象?
- 模型类/子类,其中子类类型在C++中先验未知
- C 模板继承.子类应用固定类型替换基类中的类型
- 可以将指向子类的指针分配给Varibale的超级类型
- 共享库中非模板基的模板子类导致未定义的符号类型信息'class'链接错误
- 在虚拟函数中使用子类类型参数
- C++子类类型的输出变量
- 如何返回“set”方法的子类类型
- 可以对返回子类类型的基类进行赋值操作符吗?
- 如何使子类上的操作符返回子类类型?
- 使用子类"类型转换"错误的 C++