所有派生类的显式实例化

时间:2017-05-29 18:34:52

标签: c++ templates instantiation

我有一个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 源中为ComponentSphereCollider类添加了显式实例化,因此只能编译。

例如,

Collider sCollider = gameObject.GetComponent<InnoEngine::Collider>();

除非我也添加:

,否则不会编译
template Collider &GameObject::GetComponent<Collider>();
template Collider &GameObject::AddComponent<Collider>();
GameObject.cpp 源中的

由于使用GetComponentAddComponent函数的所有内容都继承自Component类,是否有一种方法可以自动为从{继承的每个类进行显式实例化{1}}课程?

我试过Component  和template Component &GameObject::GetComponent<Component>();,但那不起作用,只给了我&#34;未解决的外部符号&#34; 错误。

我目前唯一的选择是将所有模板函数放在头文件中,但这会为template Component &GameObject::AddComponent<Component>();GetComponent模板函数公开重要的代码。

2 个答案:

答案 0 :(得分:5)

不,这是不可能的。

1)template Component &GameObject::GetComponent<Component>()是仅针对具体Component类的显式实例化。编译器找不到纯虚方法的定义,因此会出现链接器错误。

2)如果你没有添加相应的include,那么派生自Component的某些类在GameObject.cpp中是不可访问的。因此,在一般情况下,编译器甚至理论上无法获取所有继承者的列表,因为此信息仅在链接时可用。

答案 1 :(得分:3)

  

由于使用GetComponentAddComponent函数的所有内容都继承自Component类,是否有一种方法可以自动为从{{1}继承的每个类进行显式实例化} class?

简短的回答是&#34;否&#34;。

Component派生一个类就完成了。你得到一个派生类 - 没有别的,仅此而已。如果基类具有在派生类中重写的Component个成员函数,则会获得在派生类中实现的行为。

任何其他内容都必须编码。需要编写的附加代码量取决于您提供的附加功能和框架,以便于实现。

这是实现目标的一种可能方式。请注意,这会使用virtual,如果您不小心,可能会失败。

dynamic_cast