Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;多态性与类型铸造 我对C++是比较新的,我用OpenGL开发了一个基本的3D渲染引擎。 我有一个名为GeomEntity的类,它是所有几何图元的基类。我还有一个名为DefaultMaterial的类,它是所有材质的基类(由不同类型的着色器程序组成)。因为我将有许多类型的材质,如:ColorMaterial、TextureMaterial、,AnimatedMaterial等我需要在GeomEntity类中放置对材质的引用,以便从主应用程序中,我可以使用此功能设置任何材质: void GeomEntity ::addMaterial (const DefaultMaterial *mat){ material=mat;////material is the member variable pointer of type DefaultMaterial }_C++_Oop_Polymorphism - Fatal编程技术网

C++;多态性与类型铸造 我对C++是比较新的,我用OpenGL开发了一个基本的3D渲染引擎。 我有一个名为GeomEntity的类,它是所有几何图元的基类。我还有一个名为DefaultMaterial的类,它是所有材质的基类(由不同类型的着色器程序组成)。因为我将有许多类型的材质,如:ColorMaterial、TextureMaterial、,AnimatedMaterial等我需要在GeomEntity类中放置对材质的引用,以便从主应用程序中,我可以使用此功能设置任何材质: void GeomEntity ::addMaterial (const DefaultMaterial *mat){ material=mat;////material is the member variable pointer of type DefaultMaterial }

C++;多态性与类型铸造 我对C++是比较新的,我用OpenGL开发了一个基本的3D渲染引擎。 我有一个名为GeomEntity的类,它是所有几何图元的基类。我还有一个名为DefaultMaterial的类,它是所有材质的基类(由不同类型的着色器程序组成)。因为我将有许多类型的材质,如:ColorMaterial、TextureMaterial、,AnimatedMaterial等我需要在GeomEntity类中放置对材质的引用,以便从主应用程序中,我可以使用此功能设置任何材质: void GeomEntity ::addMaterial (const DefaultMaterial *mat){ material=mat;////material is the member variable pointer of type DefaultMaterial },c++,oop,polymorphism,C++,Oop,Polymorphism,但问题是,尽管所有这些材质都是从DefaultMaterial派生的,但它们都有自己独特的方法,如果我在默认情况下引用DefaultMaterial变量,则无法触发这些方法。 例如,在主应用程序中: Sphere sphere; .... sphere.addMaterial(&animMaterial);///of type AnimatedMaterial sphere.material->interpolateColor(timerSinceStart);

但问题是,尽管所有这些材质都是从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++中这种多态性的最佳实践。在爪哇或C,我会用这样的东西:

((AnimatedMaterial)sphere.material).interpolateColor(timerSinceStart);
为什么不简单地使用:

Sphere sphere;
//....
sphere.addMaterial(*animMaterial);  //of type AnimatedMaterial
animMaterial->interpolateColor(timerSinceStart);

因为
animmarterial
已经是正确的类型了?

您可以进行铸造,它看起来像:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(...);
看看你使用它的方式,它实际上不是一个指针。如果是的话,一切都会正常工作

void GeomEntity::addMaterial( DefaultMaterial *mat )
{
    material = mat; // material is the member variable pointer of type DefaultMaterial*
}
传递多态对象时,应该使用指针,而不是引用。
C++中可以使用DyrimeSkyCask来实现这一点,即我认为最接近于C特征的等价项:

AnimatedMaterial*panim=dynamic_cast(sphere.material);
如果(panim)
panim->插值颜色(timerSinceStart);

如果您确定
sphere.material
指向具有与其相关联的
插值颜色方法的对象,则可以使用
静态\u cast
(如果有疑问,则可以使用
动态\u cast
)。因此,假设
AnimatedMaterial
类具有
interpolateColor
方法:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);
static_cast(sphere.material)->插值颜色(timerSinceStart);

GeomEntity内的材质属性是通用的DefaultMaterial类型,它没有interpolateColor()method@Ben沃格特,你确定吗?内部材料也可以作为参考(仍然很奇怪,但是是的)。在材质本身上调用
interpolateColor
,在函数之外仍然可以正常工作@迈克尔,我不知道你在说什么。问题改变后,这似乎是正确的答案。@Blindy:是的,我确定。如果内部材料是参考材料,
material=mat不会重新绑定引用。但现在问题变了。@Ben,如果一个是指针,一个是引用,它甚至不会编译,所以我想我们可以假设它们的类型匹配:)对不起,这是一个输入错误。问题不在于指针,而在于当派生类的属性数据类型为基类时,我如何触发在派生类上找到的方法?@Michael IV,我不同意,真正的问题是你为什么要这么做?一个正确建模的OOP类层次结构不应该关心其实例的类型,它应该只使用基类作为接口来处理自身。@Blindy,你完全正确。所以你说如果材质引用了包含该方法的正确类>,我就不需要强制转换了?的确,你所需要做的就是将一个材质绑定到你的上下文(ogl?d3d?其他什么?),所以你需要在你的基类中有一个虚拟的
bind
函数,你可以调用它。你不在乎绑定是如何发生的。我认为这是我所知道的最接近托管语言的东西。我同意,动态\u转换比静态\u转换更适合多态性,因为它检查被转换的对象实际上是派生类类型。如果对象不是所需类型,则返回空指针。
AnimatedMaterial* panim = dynamic_cast<AnimatedMaterial*>(sphere.material);
if(panim) 
  panim->interpolateColor(timerSinceStart);
static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);