【问题标题】:How to get all derived classes from a base class in C++?如何从 C++ 中的基类获取所有派生类?
【发布时间】:2022-01-06 21:21:45
【问题描述】:

我正在用 C++ 实现一个使用 ECS(实体-组件-系统)的游戏引擎。

每个GameObject可以有多个Components(存储在GameObjectstd::vector<Component*> _components中)。

我有一种方法可以让我通过指定我想要的Component 的类型来获得GameObjectComponent

// In GameObject.h
template <typename T> T* GetComponent() {
    for (Component* c : _components) {
        if (typeid(*c) == typeid(T)) return (T*)c;
    }
    return nullptr;
}
// In main.cpp
RandomComponent* RC = gameObject.GetComponent<RandomComponent>();

现在假设我定义了Components:

class TerrainComponent { /* ... */ }
class PerlinTerrainComponent : public TerrainComponent { /* ... */ }
class FlatTerrainComponent : public TerrainComponent { /* ... */ }
// And possibly many more

并且拥有世界GameObjects,它们都附加了一个TerrainComponent的派生类。

我的问题是我需要一种方法来获取一个世界的TerrainComponent,如下所示:

TerrainComponent* TC = world.GetComponent<TerrainComponent>();

然后将任何类型的TerrainComponent 附加到世界上(实际上,这将是一个TerrainComponent 派生类)。

是否有可能在 C++ 中实现一个允许我这样做的方法(获取一个类的所有派生类),而无需手动更新 TerrainComponent 派生类的列表?

【问题讨论】:

  • 不确定是否理解您的问题,但也许如果您将 if (typeid(*c) == typeid(T)) 替换为 if(dynamic_cast(c) != nullptr ) 它会做你想做的事。

标签: c++ class templates types entity-component-system


【解决方案1】:

假设这些类都是多态/动态的(它们需要像这样使用 typeid),您可以只使用 dynamic_cast 代替:

template <typename T> T* GetComponent() {
    for (Component* c : _components) {
        if (T *tc = dynamic_cast<T *>(c)) return tc;
    }
    return nullptr;
}

【讨论】:

  • 请注意,这仅适用于对象是多态的,即具有至少一个虚拟方法。
  • @Jellyboy:typeid 方法也是如此。
  • 没想到dynamic_cast。它做了我想要的!谢谢
猜你喜欢
  • 2010-11-01
  • 2012-07-09
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
相关资源
最近更新 更多