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中文网其他相关文章!