使用抽象函数时出现未处理的异常

时间:2015-03-15 11:05:40

标签: c++ opengl virtual-functions

我正在尝试在我的程序中使用基本着色器加载,但是在加载之后,我得到一个未处理的异常弹出框。我已经创建了一个基类来完成加载通用着色器的所有常见部分。在基类中,我有一个受保护的虚函数和公共函数来处理OpenGL属性。以下是两个基本的例子:

class ShaderProgram // Base class
{
    public:
    ...

    protected:
        void bindAttribute(GLuint attribNumber, const char* variableName);
        virtual void bindAttributes() = 0; // needed for different shaders

    private:
        GLuint programID;
        void loadShaders(const char* vertFile, const char* fragFile);
}


class BasicShader : public ShaderProgram // derived class
{
    public:
    ...
    protected:
    void bindAttributes() { bindAttribute(0, "position"); }
    ...
}

现在在loadShaders()内:

programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
bindAttributes(); // Unhandled Exception pointing here

我尝试运行时遇到此错误。但如果我将bindAttributes()替换为glBindAttribLocation(programID, 0, "position")中调用的bindAttribute(),程序将按预期运行。有关导致此错误的原因的任何想法?

1 个答案:

答案 0 :(得分:2)

我发现loadShaders()ShaderProgram是私有的。根据您描述的症状和解决方法,我怀疑您从类的构造函数中调用它。

如果是这种情况,那是因为在构造过程中使用了纯虚函数。更具体地说,从基类BasicShader派生的类ShaderProgram的构建过程是这样的:

  • 首先构造类ShaderProgram的基础对象。此时对象只是ShaderProgramm。虚拟 您可以在其构造函数中调用的函数仍然是基类中定义的函数。
  • 然后派生对象构造在基础对象的顶部。只有当您输入派生对象的构造函数时,才会 BasicShader的虚函数将生效。

因此,如果您从loadShaders()的构造函数中调用ShaderProgramm,它将最终尝试在它仍然是纯虚函数(即未定义)时调用bindAttributes()

  

标准10.4 / 6:可以从构造函数中调用成员函数   (或析构函数)抽象类;制作虚拟的效果   直接或间接地为对象调用纯虚函数   从这样的构造函数(或析构函数)创建(或销毁)   未定义。

有两种解决方案:

  1. 您从loadShaders()的构造函数而不是BasicShader的构造函数中调用ShaderProgram。这要求您使功能受保护而不是私有。
  2. 您更改了类逻辑,并强制加载/初始化阶段与构造过程不同。
  3. 如果我的假设是错误的并且您没有从构造函数中调用loadShaders(),请将代码发布到您调用的位置,以及其参数的初始化,并且我将更新回答。