Maik Klein
Maik Klein

Reputation: 16148

Using interfaces and abstract classes

I am have some trouble using interfaces in c++. I am currently learning OpenGL and I want to write an small OOP abstraction layer.

#ifndef SHADER_H
#define SHADER_H

#include<glload/gl_core.h>
#include<string>
#include "filereader.h"
class IShader
{

public:
    virtual ~IShader(){}
    virtual void setShaderSource(std::string path) = 0;
    virtual bool createShader()= 0;
    virtual GLuint getHandle()= 0;
    virtual GLenum getShadertype()=0;
};
class BaseShader : public IShader
{

    GLuint shaderObj;
    std::string shaderSource;

public:

    virtual ~BaseShader();
    void setShaderSource(std::string path);
    bool createShader();
    GLuint getHandle();
    virtual GLenum getShadertype()=0;
};
class VertexShader : public BaseShader{
   public:

    GLenum getShadertype(){
        return GL_VERTEX_SHADER;
    }
};

class FragmentShader : public BaseShader{
public:
    GLenum getShadertype(){
        return GL_FRAGMENT_SHADER;
    }
};

class IShaderProgram{
public:
    virtual void attachShader(IShader &s) = 0;
    virtual void link() = 0;
    virtual void use()=0;
};

#endif // SHADER_H

As you can see I created an IShader interface and an abstract class called BaseShader. Now I want to implement all methods in BaseShader except for getShadertype().

But I somehow get forced to implement getShadertype() in BaseShader. If I don't do this I get an undefined reference error.

here is my shader.cpp

#include "shader.h"

GLenum BaseShader::getShadertype(){
    return GL_VERTEX_SHADER; // I really don't want to implement getShadertype here
}

bool BaseShader::createShader(){
    BaseShader::shaderObj = glCreateShader(BaseShader::getShadertype());
    GLint length[1];
    length[0] = BaseShader::shaderSource.size();
    const GLchar* p[1];
    p[0] = BaseShader::shaderSource.c_str();
    glShaderSource(BaseShader::getHandle(),1,p,length);

    GLint success;
    glGetShaderiv(BaseShader::getHandle(), GL_COMPILE_STATUS, &success);
        if (!success) {
            return false;
        }
    return true;


}
void BaseShader::setShaderSource(std::string path){
    FileReader fileReader(path);
    BaseShader::shaderSource = fileReader.get();
}

GLuint BaseShader::getHandle(){
    return BaseShader::shaderObj;
}

How can I tell c++ that I only want to implement getShadertype() in VertexShader , FragmentShader etc?

I probably messed up a lot of things, for example I can't even instantiate a Vertex or FragmentShader but I probably should ask another question for this.

Upvotes: 0

Views: 125

Answers (1)

Victor Sand
Victor Sand

Reputation: 2340

When a function is pure virtual ( = 0 ) all subclasses must implement it to be instantiatable. One or more pure virtual functions makes the class abstract, meaning it can't be instantiated. If the subclasses don't implement all pure virtual functions from the abstract base class, they also become abstract.

If you don't want a pure virtual function, remove the = 0.

Upvotes: 3

Related Questions