Contexte
En C, RAII (Resource Acquisition Is Initialization) est utilisé pour assurer le nettoyage automatique des ressources. Lorsqu'un objet sort de la portée, son destructeur est appelé, libérant toutes les ressources qu'il détient.
Problème
Considérons une classe C avec un objet OpenGL géré via RAII :
class BufferObject { public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } };
Lorsqu'il est utilisé dans certains scénarios, comme le stockage dans un vecteur ou le retour d'une fonction, des problèmes surviennent avec OpenGL erreurs.
Analyse
Le problème vient du manque de sémantique de copie/déplacement appropriée. Lors de la copie de l'objet (par exemple, push_back), seules les variables membres sont copiées, laissant les deux objets avec le même objet tampon OpenGL. Lors de la destruction, le premier objet supprime le tampon, rendant le deuxième objet invalide.
Solution : implémentation de la sémantique de déplacement
Pour résoudre ce problème, la classe doit être convertie en un type de déplacement uniquement, supprimant le constructeur de copie et l'opérateur d'affectation de copie. Au lieu de cela, des constructeurs de déplacement et des opérateurs d'affectation de déplacement doivent être fournis pour transférer la propriété de la ressource :
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; } };
Cela garantit qu'un seul objet possède le tampon OpenGL à un moment donné.
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!