In C , RAII (Resource Acquisition Is Initialization) is used to ensure that resources are automatically released when they are no longer needed. This pattern is commonly applied to OpenGL objects. However, sometimes issues arise when implementing RAII for OpenGL objects, causing them to stop working.
One such issue occurs when attempting to copy or move an OpenGL object wrapper. By default, C generates a copy constructor that simply copies the object's members. In the case of an OpenGL object wrapper, both copies would reference the same OpenGL object.
Consider the following code:
// An OpenGL object wrapper with RAII class BufferObject { public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } private: GLuint buff_; }; // Vector of buffer objects vector<BufferObject> bufVec; { BufferObject some_buffer; // Create buffer object // Initialize some_buffer // Copy some_buffer into the vector bufVec.push_back(some_buffer); } // Error: bufVec.back() will reference a deleted object // Function returning a buffer object BufferObject InitBuffer() { BufferObject buff; // Create buffer object // Do stuff with buff // Return a copy of buff return buff; } // Error: The returned buffer will reference a deleted object auto buff = InitBuffer();
In this example, the copy of some_buffer added to bufVec and the returned buffer from InitBuffer() both reference the same OpenGL object. When some_buffer is destroyed as its scope ends, it deletes the OpenGL object. This makes buffVec.back() and the returned buffer unusable, leading to errors.
To resolve this, the OpenGL object wrapper must be a move-only type. This can be achieved by:
BufferObject(const BufferObject &) = delete; BufferObject &operator=(const BufferObject &) = delete;
BufferObject(BufferObject &&other) : buff_(other.buff_) { other.buff_ = 0; } BufferObject &operator=(BufferObject &&other) { if (this != &other) { Release(); buff_ = other.buff_; other.buff_ = 0; } return *this; }
These modifications ensure that copying does not occur, and the ownership of the OpenGL object is moved instead of copied.
The above is the detailed content of How to Avoid Issues with OpenGL Object Wrapper Copying and Moving in C RAII?. For more information, please follow other related articles on the PHP Chinese website!