[英]Where objects created when passing parameters should be deleted?
我有這樣的事情:
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着色器對象。
因此, GLSLProgram
不應嘗試銷毀那些對象。 但是,在成功創建程序之后,構造函數應使用glDetachShader
將GLSL着色器與GLSL程序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.
另外,您還應該注意其他一些事項:
可以使用2個以上的着色器對象創建程序。 因此,您應該具有可以接受許多此類對象的備用構造函數。
可直接從字符串創建可分離的程序 ,而根本不使用着色器對象。
我應該在GLSLProgram的析構函數上將其刪除還是應該以其他方式進行管理
這取決於。
除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;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.