问题描述
在我的代码中,我希望 Component 类的所有子级都有一个唯一的 ID,该 ID 仅在它们自己的实例中共享。现在,我正在实施这样的系统:
template <class componentType>
struct Component {
static unsigned int ID;
};
示例组件:
struct Transform: public Component<Transform> {
float x,y,z;
};
ID 是使用另一种方法分配的。问题是我想要一个组件向量作为另一个 Entity 类的成员变量。此外,我希望该类具有 AddComponent()
和 GetComponent()
函数。现在,这样的实现要求我制作两个函数模板——这在必须显式实例化函数的每个版本以及在这些函数中访问的唯一成员变量是ID,我知道它在所有组件模板中都很常见。
我可以实现一个由 Component 的每个子组件覆盖的虚拟函数,但这需要我为每个子组件复制代码,并将 ID 系统与不相关的组件子组件耦合,这似乎是不好的做法。为孩子分配唯一 ID 的最佳方法是什么?如果是模板,那么如何绕过使用类的方法的问题?
解决方法
你可以做的是让 Component
从 Component_base
继承,并且这个类有一个由 get_id
实现的虚函数 Component
:
#include <iostream>
namespace {
static unsigned int next_id = 0;
template<typename T>
unsigned int get_type_id() {
static unsigned int id = ++next_id;
return id;
}
}
struct Component_base {
virtual unsigned int get_id() = 0;
};
template <class componentType>
struct Component : public Component_base {
virtual unsigned int get_id() {
return Component::ID;
}
static unsigned int ID;
};
template <class componentType>
unsigned int Component<componentType>::ID = get_type_id<componentType>();
struct Transform: public Component<Transform> {
float x,y,z;
};
struct Transform2: public Component<Transform2> {
float x,z;
};
int main() {
Transform t1;
Transform2 t2;
std::cout << t1.get_id() << std::endl;
std::cout << t2.get_id() << std::endl;
return 0;
}