动态检查使用可变继承的类的类型的最佳方法是什么

What is the best way to dynamically check the types of a class that uses variadic inheritance?

本文关键字:类型 方法 是什么 最佳 继承 检查 动态      更新时间:2023-10-16

我正在为2D游戏引擎编写一个实体组件系统,该系统使用可变模板来构建游戏对象。这是一个对象类,它只是所有组件的容器。我去掉了不相关的东西。

template<class ... Components>
class Object : public Components...{
public:
    Object(Game* game) : Components(game)...{
    }
};

组件由对象继承,但我正在努力找到检查这些组件类型的最佳方法,以便它们能够正确地相互通信。例如,Physics组件将包含对象的更新位置。Drawable组件需要获得该位置,以便可以在世界上的正确位置绘制。我想在Object中添加一个更新函数,用于更新每个组件,并传输当前组件之间可以/需要传输的任何信息。

多态性是您想要的。只需制作所有组件即可:

public Object
{
 enum TYPE{
 COMPONENT,,
 GAMEOBJECT,
 ETC,,,
};
Object(TYPE id){m_id = id;}
protected:
  TYPE m_id;
  virtual void Update(void) = 0;
  virtual void Render(void) = 0;
 public:
  void GetTypeOf(void)const{return m_id;}
};
 class Component : Object
 {
  enum COMPONENT_TYPE
 {
  COLLIDER,
  RENDERER,
  ETC,,,,
 };
   Component() : Object (COMPONENT){/**/}
   virtual void Update(void){return;}
   virtual void Render(void){return;}
   };
     class BoxCollider : Component
     {
      BoxCollider(void) : Component(BOXCOLLIDER){/**/}
      void Update(void)
      {
        //to do
         }
       void Render(void)
      {
          //to do
         }
     };

然后您可以简单地拥有Object*或Component*的数据结构你可以通过这种方式迭代:

   std::vector<Component*>::iterator components = ComponentVector.begin();
   for(;components != ComponentVector.end() ; ++components)
   {
      *(component)->Update();
       *(component)->Render();
        std::cout << "id" << *component->getTypeOf() << std::endl; 
   }

Object类从其所有Components继承,这意味着它实际上是其所有组件
您可以使用这些信息来设计update方法
例如:

#include <cassert>
struct Game { };
struct Physics {
    int position{0};
    Physics(Game *) { }
    void update(void *) { }
};
struct Drawable {
    Drawable(Game *) { }
    void update(Physics *physics) {
        physics->position = 42;
    }
};
template<class ... Components>
class Object: public Components... {
public:
    Object(Game* game) : Components(game)... { }
    void update() {
        int a[] = { (Components::update(this), 0)... };
    }
};
int main() {
    Game game;
    Object<Physics, Drawable> object{&game};
    assert(object.position == 0);
    object.update();
    assert(object.position == 42);
}

在这里,您可以看到Drawable在调用其update方法时接收Physics
这种解决方案的缺点是:

  • 组件的update方法必须获得指针参数,即使它们不需要引用任何其他组件
  • 如果存在需要引用多个组件的组件,则必须获取两个或多个指针作为update方法的参数,或者强制转换void *
相关文章: