簡體   English   中英

構造函數C ++中的虛方法

[英]Virtual method in constructor C++

我有一個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

問題是您的構造函數是整體的。 將其拆分為受保護的“預烘烤”構造函數和完成鏈接的“完成構造”輔助函數(也受保護)。 這樣,您可以自定義在構建期間但在鏈接之前發生的事情。

更通用的方法是工廠功能。

據我所知,這里有兩個選擇:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM