Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Mengelakkan Isu dengan Penyalinan dan Pemindahan Pembungkus Objek OpenGL dalam C RAII?

Bagaimana untuk Mengelakkan Isu dengan Penyalinan dan Pemindahan Pembungkus Objek OpenGL dalam C RAII?

Susan Sarandon
Susan Sarandonasal
2024-12-02 15:44:11649semak imbas

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

OpenGL Object Wrapper dalam C RAII: Penyelesaian Masalah Pemilikan Objek

Dalam C , RAII (Pemerolehan Sumber Adalah Permulaan) digunakan untuk memastikan sumber dikeluarkan secara automatik apabila ia tidak diperlukan lagi. Corak ini biasanya digunakan pada objek OpenGL. Walau bagaimanapun, kadangkala isu timbul apabila melaksanakan RAII untuk objek OpenGL, menyebabkan objek tersebut berhenti berfungsi.

Satu isu sedemikian berlaku apabila cuba menyalin atau mengalihkan pembungkus objek OpenGL. Secara lalai, C menjana pembina salinan yang hanya menyalin ahli objek. Dalam kes pembalut objek OpenGL, kedua-dua salinan akan merujuk objek OpenGL yang sama.

Pertimbangkan kod berikut:

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

Dalam contoh ini, salinan some_buffer ditambahkan pada bufVec dan penimbal yang dikembalikan daripada InitBuffer() kedua-duanya merujuk objek OpenGL yang sama. Apabila some_buffer dimusnahkan apabila skopnya tamat, ia memadamkan objek OpenGL. Ini menjadikan buffVec.back() dan penimbal yang dikembalikan tidak boleh digunakan, membawa kepada ralat.

Untuk menyelesaikan masalah ini, pembungkus objek OpenGL mestilah jenis bergerak sahaja. Ini boleh dicapai dengan:

  1. Memadamkan pembina salinan dan operator tugasan salin:
BufferObject(const BufferObject &) = delete;
BufferObject &operator=(const BufferObject &) = delete;
  1. Menyediakan pembina alih dan operator tugasan pindah:
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;
}

Pengubahsuaian ini memastikan penyalinan tidak berlaku dan pemilikan objek OpenGL dialihkan bukannya disalin.

Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Isu dengan Penyalinan dan Pemindahan Pembungkus Objek OpenGL dalam C RAII?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn