构造函数 C++ 中的虚方法
Virtual method in constructor C++
我有一个 class Shader
,在它的构造函数中有编译着色器、绑定属性然后 link 着色器程序的语句。
问题是我希望 child class 具有不同的属性,但这必须在 linking 之前发生。虚拟方法在这里不起作用。我该怎么办?
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();
}
和child class:
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;
}
问题在于您的构造函数是整体式的。将其拆分为一个 "pre-bake" 受保护的构造函数和一个 "finalize construction" 执行链接(也受保护)的辅助函数。这样您就可以自定义在构造期间但在链接之前发生的事情。
更通用的方法是工厂函数。
我有一个 class Shader
,在它的构造函数中有编译着色器、绑定属性然后 link 着色器程序的语句。
问题是我希望 child class 具有不同的属性,但这必须在 linking 之前发生。虚拟方法在这里不起作用。我该怎么办?
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();
}
和child class:
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;
}
问题在于您的构造函数是整体式的。将其拆分为一个 "pre-bake" 受保护的构造函数和一个 "finalize construction" 执行链接(也受保护)的辅助函数。这样您就可以自定义在构造期间但在链接之前发生的事情。
更通用的方法是工厂函数。