使用模板制作类型安全的C ++“组件管理器”

时间:2012-05-15 00:47:52

标签: c++ templates generics

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

以类型安全的方式请求使用泛型的组件

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

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

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

感谢。

1 个答案:

答案 0 :(得分: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)
  //...
}

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