如何将某个父级的所有子类注册到不同的类

How do I register all subclasses of a certain parent to a different class

本文关键字:注册 子类      更新时间:2023-10-16

我正在设计一个应用程序,其中多个几何基元类型(都继承基Primitive类)存储在类 Scene 的对象中。

我不想在我的main()中有一个函数,通过构造基元然后调用Scene::add(...)以编程方式创建场景,而是希望拥有某种在运行时读取的配置文件。
这将使我不必在每次更改场景时重新编译,并且似乎是一个普遍的好主意(以防其他无法编程的人可能需要在某个时候使用我的程序)

我设计了一个小方案,通过一个.ini文件定义场景,如下所示:

[primitivefoo]
type = sphere
pos = 10 20 30
radius = 5.5
[primitivebar]
type = triangle
vertexA = 10 10 -10
vertexB = ...
...

你明白了。

我的计划是让Primitive的每个子类在类Scene中注册自己的方法interpretINI(...)Scene需要某种映射 string -> void* (...) ,以便我知道 .ini 文件中的哪个类型字符串对应于 Primitive 的哪个子类。

如果这整个方法都是糟糕的设计,并且已经有一种更优雅的方式来实现我想要实现的目标,我很想听听。如果没有,如果有人能帮助我实现我的设计,我将不胜感激。我坚持如何迭代所有Primitive子类,让它们在Scene中注册自己......

你的方法对我来说听起来不错,除了名称应该映射到返回Primitive*(而不是void*)的函数。 这是一个工厂模式(在两个层面上)

此方法的一个限制是注册的工厂函数必须接受相同数量/类型的参数。 [更新:在阅读您对问题的评论后,这在您的情况下应该不是问题]。

我不知道任何自动枚举特定类的子类的方法,您需要手动注册已知类(在 main 或特殊的 register 函数中)

更新:您可以使用静态变量(类内或其他变量)绕过子类枚举,这些变量将运行特定于相关类的"寄存器"函数:

class MyShape : public Shape
{
  static int reg;
  // appropriate constructor
};
int registerMyShape();
int MyShape::reg = registerMyShape(); // this will be called at program startup

唯一的问题是,无法保证单独编译单元中的静态初始化顺序。 也许您可以使形状像模块一样并在注册表类完全初始化后"加载"它们?