使用模板制作类型安全的C++ "component manager"

making a type-safe C++ "component manager" w/ templates

本文关键字:C++ component manager 类型安全      更新时间:2023-10-16

我正在尝试在C++中创建一个类似于Unity3d中的"组件管理器"类。我想要的是一个容器类,它可以容纳某些类的派生类型,例如 BaseComponent。在 Unity 中,可以通过

经理。返回类型为 DerivedComponentType& 的 GetComponent()

我想要C++相同的界面。这样,只要通过 AddComponent 函数添加组件,从使用的角度来看,整个过程就可以保证是类型安全的。

我在这里试图避免诸如识别字符串之类的事情。我意识到我也可以通过为每个派生类型提供一个同名的静态成员函数并将其地址用作类实例的映射索引来做到这一点。我宁愿不这样做,这样组件管理器的用户就不必确保这个函数存在,如果他们选择派生自己的组件。

谢谢。

一种方法

是使用dynamic_cast。

template <typename Derived>
Derived* GetComponent (void)
{
  // componentlist is a std::vector<BaseClass*>
  for (unsigned i = 0; i < componentlist.size(); ++i)
  {
    Derived* val = dynamic_cast<Derived*>(componentlist[i]);
    if (val != 0)
      return val;
  }
  return 0;
}

如果类型与模板给出的类型不匹配,dynamic_cast将给出一个 null 指针。当然,这是必须在运行时完成的事情。在现代机器上,除非您经常这样做,否则这不会受到很大打击。还有其他一些方法可以做到这一点,这些方法将涉及更多。

您还可以考虑编写一个反射系统,该系统提供了一种更快的方法来查找类型信息,这样您就有了这样的东西:

Derived* GetComponent (MetaData *TypeIWant)
{
  if (componentlist[i]->Type() == TypeIWant)
  //...
}

从长远来看,这将是更多的工作,并且需要你做一些研究,但它可能是我所知道的唯一不需要使用字符串查找和许多人讨厌的"可怕"dynamic_cast的 c++ 选项。