Heim >Backend-Entwicklung >C++ >Wie vermeide ich Probleme beim Kopieren und Verschieben des OpenGL Object Wrapper in C RAII?
In C wird RAII (Resource Acquisition Is Initialization) verwendet, um sicherzustellen, dass Ressourcen automatisch freigegeben werden, wenn sie vorhanden sind nicht mehr benötigt. Dieses Muster wird üblicherweise auf OpenGL-Objekte angewendet. Bei der Implementierung von RAII für OpenGL-Objekte treten jedoch manchmal Probleme auf, die dazu führen, dass diese nicht mehr funktionieren.
Ein solches Problem tritt auf, wenn versucht wird, einen OpenGL-Objekt-Wrapper zu kopieren oder zu verschieben. Standardmäßig generiert C einen Kopierkonstruktor, der einfach die Mitglieder des Objekts kopiert. Im Fall eines OpenGL-Objektwrappers würden beide Kopien auf dasselbe OpenGL-Objekt verweisen.
Betrachten Sie den folgenden Code:
// 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();
In diesem Beispiel wird die Kopie von some_buffer zu bufVec und hinzugefügt Der von InitBuffer() zurückgegebene Puffer verweist beide auf dasselbe OpenGL-Objekt. Wenn some_buffer am Ende seines Gültigkeitsbereichs zerstört wird, wird das OpenGL-Objekt gelöscht. Dadurch werden buffVec.back() und der zurückgegebene Puffer unbrauchbar, was zu Fehlern führt.
Um dieses Problem zu beheben, muss der OpenGL-Objekt-Wrapper ein Nur-Verschiebungs-Typ sein. Dies kann erreicht werden durch:
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; }
Diese Änderungen stellen sicher, dass kein Kopieren erfolgt und der Besitz des OpenGL-Objekts stattdessen verschoben wird kopiert.
Das obige ist der detaillierte Inhalt vonWie vermeide ich Probleme beim Kopieren und Verschieben des OpenGL Object Wrapper in C RAII?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!