0

我正在尝试在 C++ 中创建一个类似于 Unity3d 中的“组件管理器”类。我想要的是一个容器类,它可以保存某个类的派生类型,比如 BaseComponent。在统一中,可以通过以下方式以类型安全的方式请求使用泛型的组件

manager.GetComponent() 返回类型为 DerivedComponentType&

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

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

谢谢。

4

1 回答 1

1

一种方法是使用 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 将给出一个空指针。当然,这是必须在运行时完成的事情。在现代机器上,这不会是一个巨大的打击,除非你经常这样做。还有一些其他方法可以做到这一点,这将涉及更多。

您还可以考虑编写一个反射系统,它可以更快地查找类型信息,这样您就有了这样的东西:

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

从长远来看,这将是更多的工作,并且需要您进行一些研究,但这可能是我所知道的唯一一个不需要使用字符串查找和“可怕的”dynamic_cast 的 c++ 选项这么多人们往往讨厌。

于 2012-05-17T02:42:35.730 回答