我有类似的东西:
class GLSLShader {
public:
GLSLShader(GLenum);
~GLSLShader();
};
class GLSLProgram {
public:
GLSLProgram(GLSLShader *, GLSLShader *);
~GLSLProgram();
private:
GLSLShader *m_VertexShader;
GLSLShader *m_FragmentShader;
};
glslprogram构造函数将被称为:
GLSLProgram program(new GLSLShader(GL_VERTEX_SHADER), new GLSLShader(GL_FRAGMENT_SHADER));
我的问题是我应该在哪里删除分配的着色器对象。我应该在GLSLPROGRAM的破坏器上删除它,还是应该使用以下代码之类的内容进行不同的管理?
?GLSLShader *vertex = new GLSLShader(GL_VERTEX_SHADER);
GLSLShader *fragment = new GLSLShader(GL_FRAGMENT_SHADER);
GLSLProgram program(vertex, fragment);
delete vertex;
delete fragment;
您有两个基本问题。
第一个问题是您错误地使用了RAII对象。RAII对象的点是使用自动变量来管理对象寿命,而不是明确使用new
和delete
。通过在GLSLShader
上使用new
,而无需将该指针包装到RAII容器中,您就可以有效地减轻攻击者的作用。
您的GLSLProgram
构造函数不应通过指针采用对象。它应该将它们带到const&
。这使呼叫者更容易决定这些对象应该持续多长时间。
第二个问题是合乎逻辑的。GLSLProgram
没有理由负责其给出的着色器对象的破坏。这应该取决于调用代码,因为GLSL着色器对象可以是重复使用。
因此, 总的来说,您的代码应该看起来像这样: 另外,您应该知道其他一些事情: 可以使用超过2个着色器对象创建程序。因此,您应该拥有可以采用许多此类对象的替代构造函数。 可以直接从字符串中创建可分离程序,而无需使用着色器对象。GLSLProgram
不应尝试摧毁这些对象。但是成功创建程序后,构造函数应使用glDetachShader
。GLSLShader vertex(GL_VERTEX_SHADER);
GLSLShader fragment(GL_FRAGMENT_SHADER);
//Fill `vertex` and `fragment` with actual shader code.
GLSLProgram program(vertex, fragment);
//Destructors for `vertex` and `fragment` will take care of themselves.
我应该在glslprogram的驱动器上删除它还是应该对其进行不同的管理
这取决于。
除了GLSLProgram
以外,还有其他需要访问这些动态对象吗?这样的对象可以超过指向它们的GLSLProgram
实例吗?如果是两者,则不能仅由program
进行内存。
无论哪种情况,您都会发现编写正确的程序要容易得多,如果将内存管理委派给了仅负责破坏动态对象的RAII对象。
另一方面,如果GLSLProgram
只能仅管理内存,那么当然也应该是分配它们的一个。此外,似乎根本没有理由使用动态分配。我建议使用成员对象,除非有特定原因不这样做。
考虑到问题中的尝试,我建议以下内容:
class GLSLProgram {
public:
GLSLProgram():
m_VertexShader(GL_VERTEX_SHADER),
m_FragmentShader(GL_FRAGMENT_SHADER) {}
private:
GLSLShader m_VertexShader;
GLSLShader m_FragmentShader;
};