在 C++ 中调用虚拟方法会导致访问冲突

Calling virtual method in c++ gives access violation

我有一个名为 Renderable 的 class,带有一个纯虚方法 draw()

class Renderable : public QOpenGLFunctions
{
public:
   virtual void draw() = 0;
}

我有一个 class 继承自 Renderable 和 Transformable 的 GeomObject(Transformable 是常规的 class,不是虚拟的)

class GeomObject : public Renderable, public Transformable

GeomObject 重载了 draw() 方法。 另外,我有一个场景 class,我想在其中循环场景对象,如果它们是可渲染的,则绘制它们。它们每个都有设置为 true 的 isRenderable bool 变量。在这种情况下,所有这些对象都是 GeomObjects。这里的SceneObject是常规的class(不是虚拟的)

for ( unsigned int i = 0; i < this->sceneObjects.count(); i++ ) {
    SceneObject* obj = this->sceneObjects[i];
    if ( obj->isRenderable ) {          
        ( ( Renderable* )obj )->draw(); //access violation
    }
} 

这是我遇到访问冲突的地方。但是如果我直接转换为 GeomObject* 然后调用 draw(),一切正常。

for ( unsigned int i = 0; i < this->sceneObjects.count(); i++ ) {
    SceneObject* obj = this->sceneObjects[i];
    if ( obj->isRenderable ) {          
        ( ( GeomObject* )obj )->draw(); // this works
    }
} 

我做错了什么?

这是我的 class 层次结构:

class Renderable : public QOpenGLFunctions 
class SceneObject 
class Transformable : public SceneObject 
class GeomObject : public Renderable, public Transformable

class 层次结构的可验证示例(有效,所以问题可能出在其他地方)

#include <iostream>
using namespace std;
class QOpenGLFunctions
{};

class Renderable : public QOpenGLFunctions
{
public:
    virtual void draw() = 0;
};

class SceneObject
{};

class Transformable : public SceneObject
{};

class GeomObject : public Renderable, public SceneObject
{
public:
    void draw(){
        cout << "Draw() is called"; 
    }
};

int main() {
    GeomObject * obj = new GeomObject();
    ((Renderable*)obj)->draw();
    return 0;
}

工作示例不是您描述的问题的有效示例。在您的问题中,您尝试将 SceneObject* 转换为 Renderable*。在工作示例中,您将 GeomObject* 转换为 Renderable*。与 Renderable 相比,SceneObject 位于继承链中的不同分支,我不知道如何将对象直接转换为另一个分支。

如果您绝对想在 non-working 示例中使用 Renderable*,您应该能够先转换为 GeomObject*,然后再转换为 Renderable*

此外,正如已经指出的那样:使用 static_castdynamic_cast 而不是 C-style 强制转换。