C++多态性和类型铸造
我对C++比较新,我一直在使用OpenGL开发基本的3D渲染引擎。我有以下问题: 我有一个名为GeomEntity的类,它是所有几何图元的基类。我有另一个名为DefaultMaterial的类,它是所有材质的基类(由不同类型的着色器程序组成)。因为我将有许多类型的材质,如:ColorMaterial,TextureMaterial,AnimatedMaterial等等,我需要放置参考GeomEntity类的材料,以便从主应用程序,我可以设置任何使用该功能的材料:C++多态性和类型铸造
void GeomEntity ::addMaterial (const DefaultMaterial *mat){
material=mat;////material is the member variable pointer of type DefaultMaterial
}
但事实是,虽然所有的这些材料是从DefaultMaterial派生的,它们都有独特的方法,如果我将它们默认引用到DefaultMaterial的变量,我不能触发它们。 因此,例如在主应用程序:
Sphere sphere;
....
sphere.addMaterial(&animMaterial);///of type AnimatedMaterial
sphere.material->interpolateColor(timerSinceStart);
///doesn't happen anything as the sphere.material is
/// of type DefaultMaterial that has no interpolateColor() method
我知道我可以使用模板或石膏,但我想听到这种多态性在C++。在Java中的最佳做法或C#我真的使用这样的:
((AnimatedMaterial)sphere.material).interpolateColor(timerSinceStart);
在C++中,你可以做到这一点使用dynamic_cast的,那就是我相信C#功能最接近的等效:
AnimatedMaterial* panim = dynamic_cast<AnimatedMaterial*>(sphere.material);
if(panim)
panim->interpolateColor(timerSinceStart);
为什么不能简单地用:
Sphere sphere;
//....
sphere.addMaterial(*animMaterial); //of type AnimatedMaterial
animMaterial->interpolateColor(timerSinceStart);
因为animMaterial
已经正确类型的?
的GeomEntity内部的材料属性是不具有interpolateColor()方法 –
@Ben福格特,你确定通用DefaultMaterial类型的?内部材料也可以作为参考(仍然很奇怪,但是..)。在材质上调用'interpolateColor'应该可以在函数外正常工作。 @迈克尔,我不知道你在说什么。 – Blindy
问题发生变化后,这似乎是正确的答案。 –
你可以施放,它看起来像:
static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(...);
但使用Blindy的方式,它的清洁。
原来的答复为无效的问题编辑:
你说:
//material is the member variable pointer of type DefaultMaterial
在你使用它的方式来看,它实际上不是一个指针。如果是的话,一切都会正常工作。
void GeomEntity::addMaterial(DefaultMaterial *mat)
{
material = mat; // material is the member variable pointer of type DefaultMaterial*
}
当传递多态对象时,应该使用指针而不是引用。
对不起,这是一个错字。问题不在于指针,而是当我们的属性数据类型是基类时,如何触发派生类中的方法? –
@Michael IV,我不同意,真正的问题是*你为什么要这么做*?一个正确建模的OOP类层次结构不应该关心其实例的类型,它应该仅以基类作为接口来处理自身。 – Blindy
@布林迪,你说得对,你说我不需要投射,如果材料引用了包含该方法的正确类>>? –
如果您确信sphere.material
指向具有interpolateColor
与之相关联的方法的对象,你可以使用static_cast
(如果有疑问,那么你会使用dynamic_cast
)。所以假设AnimatedMaterial
类有interpolateColor
方法:
static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);
我认为这与我所了解的托管语言最接近。 –