Виртуальный метод в конструкторе C ++ - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть класс Shader, в его конструкторе есть операторы для компиляции шейдера, связывания атрибутов и последующего связывания программы шейдера.Проблема в том, что я хотел бы, чтобы дочерний класс имел разные атрибуты, но это должно произойти до связывания.Виртуальные методы здесь не работают.Что мне делать?

Shader::Shader(const char* v, const char* f) {
    program = glCreateProgram();

    const char* vsrc = nullptr;
    const char* fsrc = nullptr;

    tls::readTextFile(std::ifstream(v, std::ios::binary), vsrc);
    tls::readTextFile(std::ifstream(f, std::ios::binary), fsrc);

    m_vertShader = compile(vsrc, GL_VERTEX_SHADER);
    m_fragShader = compile(fsrc, GL_FRAGMENT_SHADER);

    glAttachShader(program, m_vertShader);
    glAttachShader(program, m_fragShader);

    bindAttribs(); // it must happen before linking, in child class too.

    glLinkProgram(program);

    getUniforms();
    setUniforms();
}

и дочерний класс:

void BasicShader::bindAttribs() {
    bindAttribute(0, "pos");
    bindAttribute(2, "vt");
} // this method is not called

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Проблема в том, что ваш конструктор монолитный.Разделите его на защищенный конструктор "pre-bake" и вспомогательную функцию "finalize construction", которая выполняет связывание (также защищенное).Таким образом, вы можете настроить то, что происходит во время построения, но перед компоновкой.

Более общим подходом будет фабричная функция.

0 голосов
/ 26 декабря 2018

Насколько я вижу, здесь есть два варианта:

1.Передайте атрибуты конструктору в качестве параметра

Shader::Shader(const char* v, const char* f,
    const std::vector<std::pair<int, std::string>> &attrs)
    /* Or some simpler type with the same functionality */
{
    ...
    for (auto &&attr : attrs)
        bindAttr(attr.first, attr.second);
    ...
}

2.Переместить всю инициализацию из конструктора в отдельный метод

bool Shader::initialize(const char* v, const char* f)
{
    // Here you actually can use virtual methods, yay!
    // ...and even report errors via return value (unless you were planning to use exceptions)
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...