我有一个Component
课程:
class Component
{
}
然后是一个继承自它的Collider
类:
class Collider :public Component
{
}
继承自SphereCollider
:
Collider
class SphereCollider :public Collider
{
}
最后,您可以使用GameObject
类添加或删除组件。
GameObject.h 标题:
class GameObject
{
//Add functionality
template <class T>
T& AddComponent();
//Get functionality
template <typename T>
T& GetComponent();
}
GameObject.cpp 来源:
template <typename T>
T& GameObject::AddComponent(){}
template <typename T>
T& GameObject::GetComponent(){}
//Explicit instantiation
template Component &GameObject::GetComponent<Component>();
template Component &GameObject::AddComponent<Component>();
template SphereCollider &GameObject::GetComponent<SphereCollider>();
template SphereCollider &GameObject::AddComponent<SphereCollider>();
一切都很好。我可以在没有指针的情况下从GameObject添加或获取组件:
GameObject gameObject;
SphereCollider sCollider1 = gameObject.AddComponent<SphereCollider>();
SphereCollider sCollider2 = gameObject.GetComponent<SphereCollider>();
Component sCollider3 = gameObject.GetComponent<Component>();
问题:
我需要将它用作库并隐藏源文件。由于我在 GameObject.cpp 源中为Component
和SphereCollider
类添加了显式实例化,因此只能编译。
例如,
Collider sCollider = gameObject.GetComponent<InnoEngine::Collider>();
除非我也添加:
,否则不会编译template Collider &GameObject::GetComponent<Collider>();
template Collider &GameObject::AddComponent<Collider>();
GameObject.cpp 源中的。
由于使用GetComponent
和AddComponent
函数的所有内容都继承自Component
类,是否有一种方法可以自动为从{继承的每个类进行显式实例化{1}}课程?
我试过Component
和template Component &GameObject::GetComponent<Component>();
,但那不起作用,只给了我&#34;未解决的外部符号&#34; 错误。
我目前唯一的选择是将所有模板函数放在头文件中,但这会为template Component &GameObject::AddComponent<Component>();
和GetComponent
模板函数公开重要的代码。
答案 0 :(得分:5)
1)template Component &GameObject::GetComponent<Component>()
是仅针对具体Component
类的显式实例化。编译器找不到纯虚方法的定义,因此会出现链接器错误。
2)如果你没有添加相应的include,那么派生自Component
的某些类在GameObject.cpp中是不可访问的。因此,在一般情况下,编译器甚至理论上无法获取所有继承者的列表,因为此信息仅在链接时可用。
答案 1 :(得分:3)
由于使用
GetComponent
和AddComponent
函数的所有内容都继承自Component
类,是否有一种方法可以自动为从{{1}继承的每个类进行显式实例化} class?
简短的回答是&#34;否&#34;。
从Component
派生一个类就完成了。你得到一个派生类 - 没有别的,仅此而已。如果基类具有在派生类中重写的Component
个成员函数,则会获得在派生类中实现的行为。
任何其他内容都必须编码。需要编写的附加代码量取决于您提供的附加功能和框架,以便于实现。
这是实现目标的一种可能方式。请注意,这会使用virtual
,如果您不小心,可能会失败。
dynamic_cast