Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah RAII dengan Objek OpenGL dalam C Boleh Membawa kepada Kelakuan Tidak Dijangka Apabila Menyalin atau Memindahkan Objek?

Bagaimanakah RAII dengan Objek OpenGL dalam C Boleh Membawa kepada Kelakuan Tidak Dijangka Apabila Menyalin atau Memindahkan Objek?

Susan Sarandon
Lepaskan: 2024-11-29 21:12:17
asal
691 orang telah melayarinya

How Can RAII with OpenGL Objects in C   Lead to Unexpected Behavior When Copying or Moving Objects?

RAII dengan OpenGL Objects dalam C : Memahami Isu Tersembunyi

Dalam pengaturcaraan berorientasikan objek C, pemerolehan sumber adalah permulaan (RAII) ialah teknik yang digunakan untuk mengurus sumber dengan cekap. Apabila menggunakan objek OpenGL dalam kelas C, adalah perkara biasa untuk menggunakan RAII untuk memastikan objek OpenGL dikeluarkan dengan betul apabila kelas dimusnahkan.

Pertimbangkan coretan kod berikut:

class BufferObject
{
private:
  GLuint buff_;

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

  ~BufferObject()
  {
    glDeleteBuffers(1, &buff_);
  }
};
Salin selepas log masuk

Kelas ini nampaknya melaksanakan RAII dengan betul untuk objek OpenGL. Walau bagaimanapun, masalah timbul apabila kelas disalin atau dialihkan, seperti yang ditunjukkan oleh kod berikut:

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.
Salin selepas log masuk

Dalam senario ini, objek OpenGL menjadi tidak boleh digunakan, membawa kepada ralat.

Sebabnya kerana tingkah laku ini terletak pada pembina salinan lalai dan pengendali tugasan yang dijana oleh pengkompil. Operasi ini hanya menyalin ahli objek, menghasilkan berbilang objek C yang merujuk kepada objek OpenGL asas yang sama. Apabila objek C asal dimusnahkan, ia mengeluarkan objek OpenGL, menyebabkan objek lain merujuk sumber yang dimusnahkan.

Untuk menyelesaikan isu ini, kelas BufferObject hendaklah jenis bergerak sahaja. Ini bermakna menghapuskan pembina salinan dan pengendali tugasan dan menyediakan persamaan pergerakan yang memindahkan pemilikan objek OpenGL kepada objek baharu.

class BufferObject
{
private:
  GLuint buff_;

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

  BufferObject(const BufferObject &) = delete;
  BufferObject &operator=(const BufferObject &) = delete;

  BufferObject(BufferObject &&other) : buff_(other.buff_)
  {
    other.buff_ = 0;
  }

  BufferObject &operator=(BufferObject &&other)
  {
    //ALWAYS check for self-assignment
    if(this != &other)
    {
      Release();
      buff_ = other.buff_;
      other.buff_ = 0;
    }

    return *this;
  }

  ~BufferObject() {Release();}

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

//Other members.
};
Salin selepas log masuk

Dengan perubahan ini, kelas memastikan objek OpenGL diurus dengan betul dan dikeluarkan, walaupun semasa menyalin atau memindahkan kelas.

Atas ialah kandungan terperinci Bagaimanakah RAII dengan Objek OpenGL dalam C Boleh Membawa kepada Kelakuan Tidak Dijangka Apabila Menyalin atau Memindahkan Objek?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan