Home >Backend Development >C++ >How to Avoid Issues with OpenGL Object Wrapper Copying and Moving in C RAII?

How to Avoid Issues with OpenGL Object Wrapper Copying and Moving in C RAII?

Susan Sarandon
Susan SarandonOriginal
2024-12-02 15:44:11621browse

How to Avoid Issues with OpenGL Object Wrapper Copying and Moving in C   RAII?

OpenGL Object Wrapper in C RAII: Troubleshooting Object Ownership

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:

  1. Deleting the copy constructor and copy assignment operator:
BufferObject(const BufferObject &) = delete;
BufferObject &operator=(const BufferObject &) = delete;
  1. Providing move constructor and move assignment operator:
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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn