C++多态性和类型转换

发布于 2024-12-05 17:43:16 字数 1020 浏览 1 评论 0原文

我对 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

  }

但是事情问题是,虽然所有这些材质都源自 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);

I am relatively new to C++ and I have been working on a basic 3D rendering engine using OpenGL.I have the following issue:
I have a class called GeomEntity which is the base class for all geometry primitives.I have another class called DefaultMaterial which is the base class for all materials(consists of different types of shader programs) .Because I am going to have many types of materials like :ColorMaterial,TextureMaterial,AnimatedMaterial and so on I need to put a reference to the material in GeomEntity class so that from the main app I can set any of the material with this function:

  void GeomEntity ::addMaterial (const DefaultMaterial *mat){

         material=mat;////material is the member variable pointer of type DefaultMaterial

  }

But the thing is that although all of those materials are derived from the DefaultMaterial they all have got their unique methods which I can't trigger if I reference them to the variable of DefaultMaterial by default.
So for example in the main application:

  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

I know I have can use templates or casts but I would like to hear about the best practices of this kind of polymorphism in C++ .In Java or C# I would really use something like this:

((AnimatedMaterial)sphere.material).interpolateColor(timerSinceStart);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

尛丟丟 2024-12-12 17:43:16

在C++中,你可以使用dynamic_cast来做到这一点,我相信这与C#功能最接近:

AnimatedMaterial* panim = dynamic_cast<AnimatedMaterial*>(sphere.material);
if(panim) 
  panim->interpolateColor(timerSinceStart);

In C++ you can do this using dynamic_cast, that is I believe closest equivalent of that C# feature:

AnimatedMaterial* panim = dynamic_cast<AnimatedMaterial*>(sphere.material);
if(panim) 
  panim->interpolateColor(timerSinceStart);
烟─花易冷 2024-12-12 17:43:16

如果您确定 sphere.material 指向一个具有与之关联的 interpolateColor 方法的对象,则可以使用 static_cast (如果有疑问) ,那么您将使用dynamic_cast)。因此假设 AnimatedMaterial 类具有 interpolateColor 方法:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);

If you are sure that sphere.material points to an object that has interpolateColor method associated with it, you can use static_cast (if there were doubts, then you would use dynamic_cast). So assuming that AnimatedMaterial class has interpolateColor method:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(timerSinceStart);
2024-12-12 17:43:16

你可以投射,它看起来像:

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*
}

传递多态对象时,应该使用指针,而不是引用。

You can cast, it would look like:

static_cast<AnimatedMaterial*>(sphere.material)->interpolateColor(...);

But use Blindy's way, it's cleaner.


Original answer made invalid by question edit:


You said:

//material is the member variable pointer of type DefaultMaterial

Looking at the way you're using it, it's not actually a pointer. If it were, everything would be working properly.

void GeomEntity::addMaterial( DefaultMaterial *mat )
{
    material = mat; // material is the member variable pointer of type DefaultMaterial*
}

When passing around polymorphic objects, you should be using pointers, not references.

青瓷清茶倾城歌 2024-12-12 17:43:16

为什么不简单地使用:

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

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

Why not simply use:

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

since animMaterial is already of the right type?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文