C RAII 類別中的OpenGL 物件:陷阱與解決方案
在C RAII 類別中,當物件超出範圍時,成員會自動釋放以確保資源重新分配。然而,在此類中處理 OpenGL 物件時,可能會出現意想不到的後果。
考慮以下程式碼:
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } // Other members };
此類管理一個 OpenGL 緩衝區對象,應在析構函數。但是,當嘗試複製或移動建構這些物件時,會發生意外錯誤。
問題源自於缺乏明確複製或移動建構子/賦值運算子。編譯器產生的複製建構函式只是複製成員變量,導致兩個物件共用同一個 OpenGL 緩衝區物件。當一個物件被銷毀時,另一個物件就會失效,從而導致錯誤。
同樣,InitBuffer函數:
BufferObject InitBuffer() { BufferObject buff; // Do stuff with `buff` return buff; }
也會失敗,因為buff被複製到回傳值後被銷毀。
為了解決這些陷阱,應該使用僅移動類型。在C 中,這意味著刪除複製建構子和複製賦值運算符,同時提供轉移所有權的移動等效項:
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } BufferObject(const BufferObject&) = delete; // no copy constructor BufferObject& operator=(const BufferObject&) = delete; // no copy assignment BufferObject(BufferObject&& other) : buff_(other.buff_) { other.buff_ = 0; } BufferObject& operator=(BufferObject&& other) { if(this != &other) { Release(); // release current resource buff_ = other.buff_; other.buff_ = 0; } return *this; } ~BufferObject() { Release(); } void Release() { if(buff_) glDeleteBuffers(1, &buff_); } // Other members };
透過這些更改,複製和移動BufferObject 實例變得安全,並且OpenGL 資源可以在RAII 模式。
以上是如何安全管理 C RAII 類別中的 OpenGL 物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!