Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Mengelakkan Isu dengan Penyalinan dan Pemindahan Pembungkus Objek OpenGL dalam C RAII?
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:
BufferObject(const BufferObject &) = delete; BufferObject &operator=(const BufferObject &) = 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; }
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!