Maison >développement back-end >C++ >Comment éviter les problèmes de copie et de déplacement du wrapper d'objet OpenGL dans C RAII ?
En C, RAII (Resource Acquisition Is Initialization) est utilisé pour garantir que les ressources sont automatiquement libérées lorsqu'elles sont n'est plus nécessaire. Ce modèle est couramment appliqué aux objets OpenGL. Cependant, des problèmes surviennent parfois lors de l'implémentation de RAII pour les objets OpenGL, les empêchant de fonctionner.
L'un de ces problèmes se produit lors de la tentative de copie ou de déplacement d'un wrapper d'objet OpenGL. Par défaut, C génère un constructeur de copie qui copie simplement les membres de l'objet. Dans le cas d'un wrapper d'objet OpenGL, les deux copies feraient référence au même objet OpenGL.
Considérez le code suivant :
// 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();
Dans cet exemple, la copie de some_buffer ajoutée à bufVec et le tampon renvoyé par InitBuffer() fait référence au même objet OpenGL. Lorsque some_buffer est détruit à la fin de sa portée, il supprime l'objet OpenGL. Cela rend buffVec.back() et le tampon renvoyé inutilisables, entraînant des erreurs.
Pour résoudre ce problème, le wrapper d'objet OpenGL doit être de type déplacement uniquement. Ceci peut être réalisé en :
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; }
Ces modifications garantissent qu'aucune copie ne se produit et que la propriété de l'objet OpenGL est déplacée au lieu de copié.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!