Rumah >pembangunan bahagian belakang >C++ >Mengapa Objek OpenGL Saya dalam Kelas C RAII Berhenti Berfungsi Selepas Menyalin?

Mengapa Objek OpenGL Saya dalam Kelas C RAII Berhenti Berfungsi Selepas Menyalin?

Barbara Streisand
Barbara Streisandasal
2024-11-26 19:14:09610semak imbas

Why Do My OpenGL Objects in C   RAII Classes Stop Working After Copying?

OpenGL Objects dalam Kelas C RAII: Mengapa Mereka Berhenti Berfungsi selepas Menyalin

Dalam C , adalah perkara biasa untuk menggunakan RAII (Pemerolehan Sumber Adalah Permulaan ) untuk memastikan objek dibersihkan secara automatik apabila dimusnahkan. Walau bagaimanapun, apabila berurusan dengan objek OpenGL, adalah penting untuk memahami cara corak RAII mempengaruhi penggunaan objek.

Pertimbangkan kelas berikut yang merangkum objek penimbal OpenGL:

class BufferObject {
private:
  GLuint buff_;

public:
  BufferObject() { glGenBuffers(1, &buff_); }
  ~BufferObject() { glDeleteBuffers(1, &buff_); }

Pada mulanya, kelas ini nampaknya berfungsi dengan betul. Walau bagaimanapun, isu timbul apabila melakukan operasi tertentu:

vector<BufferObject> bufVec;
{
  BufferObject some_buffer;
  // Initialize some_buffer;
  bufVec.push_back(some_buffer);
}
bufVec.back(); // buffer doesn't work.

BufferObject InitBuffer() {
  BufferObject buff;
  // Do stuff with `buff`
  return buff;
}

auto buff = InitBuffer(); // Returned buffer doesn't work.

Menyalin kelas melalui penyataan push_back atau return menyebabkan ralat OpenGL yang tidak dijangka. Untuk memahami sebabnya, anda perlu mendalami mekanik RAII.

Apabila objek disalin, pembina salinan lalai digunakan (dengan andaian wujud). Dalam kes ini, pembina salinan lalai hanya menyalin pembolehubah ahli. Walau bagaimanapun, salinan ini termasuk pemegang objek OpenGL (buff_), yang unik untuk setiap objek.

Masalah timbul apabila objek asal dimusnahkan (pada penghujung skop pertama dalam contoh kami). Pemusnah cuba memadam objek OpenGL, yang telah disalin oleh objek baharu. Objek OpenGL yang yatim piatu ini tidak boleh digunakan lagi dan membawa kepada ralat.

Untuk menyelesaikan isu ini, adalah penting untuk menentukan salinan tersuai dan memindahkan semantik untuk pembalut objek OpenGL. Pendekatan ini memastikan bahawa rujukan objek OpenGL dipindahkan dengan betul antara objek tanpa menyebabkan konflik.

Menggerakkan objek melibatkan pemindahan pemilikan sumbernya ke objek lain. Daripada menyalin, sumber objek diberikan kepada objek baharu dan objek asal dibiarkan dalam keadaan yang sah tetapi kosong. Pendekatan ini menghalang kemungkinan konflik dan memastikan objek OpenGL kekal sah.

Dalam kelas BufferObject yang diubah suai di bawah, pembina salinan dan operator tugasan salinan dipadamkan dan semantik pindah dilaksanakan:

class BufferObject {
private:
  GLuint buff_;

public:
  BufferObject() { glGenBuffers(1, &buff_); }

  BufferObject(const BufferObject& other) = delete;
  BufferObject& operator=(const BufferObject& other) = 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;
  }

  ~BufferObject() { Release(); }

  void Release() {
    if (buff_)
      glDeleteBuffers(1, &buff_);
  }
};

Dengan melaksanakan semantik bergerak, anda boleh membuat pembalut RAII bergerak sahaja untuk objek OpenGL. Pendekatan ini membolehkan pengendalian objek OpenGL yang selamat dan cekap dalam C .

Atas ialah kandungan terperinci Mengapa Objek OpenGL Saya dalam Kelas C RAII Berhenti Berfungsi Selepas Menyalin?. 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