Hintergrund
In C ist RAII (Resource Acquisition Is Initialization). eingesetzt, um eine automatische Ressourcenbereinigung sicherzustellen. Wenn ein Objekt den Gültigkeitsbereich verlässt, wird sein Destruktor aufgerufen und gibt alle darin enthaltenen Ressourcen frei.
Problem
Stellen Sie sich eine C-Klasse mit einem über RAII verwalteten OpenGL-Objekt vor:
class BufferObject { public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } };
Bei der Verwendung in bestimmten Szenarien, z. B. beim Speichern in einem Vektor oder beim Zurückkehren von einer Funktion, treten Probleme mit OpenGL auf Fehler.
Analyse
Das Problem ist auf das Fehlen der richtigen Kopier-/Verschiebesemantik zurückzuführen. Beim Kopieren des Objekts (z. B. push_back) werden nur die Mitgliedsvariablen kopiert, sodass beide Objekte dasselbe OpenGL-Pufferobjekt haben. Bei der Zerstörung löscht das erste Objekt den Puffer, wodurch das zweite Objekt ungültig wird.
Lösung: Bewegungssemantik implementieren
Um dieses Problem zu beheben, sollte die Klasse in a konvertiert werden Nur-Verschiebungstyp, wobei der Kopierkonstruktor und der Kopierzuweisungsoperator entfernt werden. Stattdessen sollten Verschiebungskonstruktoren und Verschiebungszuweisungsoperatoren bereitgestellt werden, die den Besitz der Ressource übertragen:
class BufferObject { public: 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; } };
Dadurch wird sichergestellt, dass jeweils nur ein Objekt den OpenGL-Puffer besitzt.
Das obige ist der detaillierte Inhalt vonWie vermeide ich OpenGL-Fehler bei der Verwendung von RAII in C?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!