首頁 >後端開發 >C++ >如何避免在 C RAII 中複製和移動 OpenGL 物件包裝器時出現問題?

如何避免在 C RAII 中複製和移動 OpenGL 物件包裝器時出現問題?

Susan Sarandon
Susan Sarandon原創
2024-12-02 15:44:11623瀏覽

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

C RAII 中的OpenGL 物件包裝器:物件所有權故障排除

在C 中,RAII(資源取得即初始化)用於確保資源在使用時自動釋放不再需要。此模式通常應用於 OpenGL 物件。然而,在為 OpenGL 物件實作 RAII 時有時會出現問題,導致它們停止運作。

嘗試複製或移動 OpenGL 物件包裝器時會出現這樣的問題。預設情況下,C 產生一個複製建構函數,它只複製物件的成員。在 OpenGL 物件包裝器的情況下,兩個副本都會引用相同的 OpenGL 物件。

考慮以下程式碼:

// 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();

在此範例中,將 some_buffer 的副本新增至 bufVec 並從 InitBuffer() 傳回的緩衝區都引用相同的 OpenGL 物件。當 some_buffer 在其範圍結束時被銷毀時,它會刪除 OpenGL 物件。這使得 buffVec.back() 和傳回的緩衝區不可用,從而導致錯誤。

要解決此問題,OpenGL 物件包裝器必須是僅移動類型。這可以透過以下方式實現:

  1. 刪除複製建構子和複製賦值運算子:
BufferObject(const BufferObject &) = delete;
BufferObject &operator=(const BufferObject &) = delete;
  1. 提供移動建構子和移動賦值運算子:
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;
}

這些修改確保不會發生複製,以及OpenGL物件的所有權被移動而不是被複製。

以上是如何避免在 C RAII 中複製和移動 OpenGL 物件包裝器時出現問題?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn