RAII mit OpenGL-Objekten in C: Versteckte Probleme verstehen
In der objektorientierten C-Programmierung ist die Ressourcenbeschaffung Initialisierung (RAII). eine Technik zur effizienten Verwaltung von Ressourcen. Bei der Verwendung von OpenGL-Objekten innerhalb von C-Klassen ist es üblich, RAII zu verwenden, um sicherzustellen, dass das OpenGL-Objekt korrekt freigegeben wird, wenn die Klasse zerstört wird.
Beachten Sie den folgenden Codeausschnitt:
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } };
Diese Klasse scheint RAII für OpenGL-Objekte korrekt zu implementieren. Beim Kopieren oder Verschieben der Klasse treten jedoch Probleme auf, wie der folgende Code zeigt:
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.
In diesen Szenarien werden die OpenGL-Objekte unbrauchbar, was zu Fehlern führt.
Der Grund Der Grund für dieses Verhalten liegt in den vom Compiler generierten Standardkopierkonstruktoren und Zuweisungsoperatoren. Diese Vorgänge kopieren einfach die Mitglieder des Objekts, was dazu führt, dass mehrere C-Objekte auf dasselbe zugrunde liegende OpenGL-Objekt verweisen. Wenn das ursprüngliche C-Objekt zerstört wird, gibt es das OpenGL-Objekt frei, wodurch die anderen Objekte auf eine zerstörte Ressource verweisen.
Um dieses Problem zu beheben, sollte die BufferObject-Klasse ein Typ sein, der nur verschoben werden kann. Das bedeutet, den Kopierkonstruktor und den Zuweisungsoperator zu eliminieren und Verschiebungsäquivalente bereitzustellen, die den Besitz des OpenGL-Objekts auf das neue Objekt übertragen.
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. };
Mit diesen Änderungen stellt die Klasse sicher, dass das OpenGL-Objekt korrekt verwaltet und verwaltet wird freigegeben, auch beim Kopieren oder Verschieben der Klasse.
Das obige ist der detaillierte Inhalt vonWie kann RAII mit OpenGL-Objekten in C zu unerwartetem Verhalten beim Kopieren oder Verschieben von Objekten führen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!