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 ?

Comment éviter les problèmes de copie et de déplacement du wrapper d'objet OpenGL dans C RAII ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-02 15:44:11618parcourir

How to Avoid Issues with OpenGL Object Wrapper Copying and Moving in C   RAII?

OpenGL Object Wrapper en C RAII : Dépannage de la propriété des objets

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 :

  1. Supprimer le constructeur de copie et l'opérateur d'affectation de copie :
BufferObject(const BufferObject &) = delete;
BufferObject &operator=(const BufferObject &) = delete;
  1. Fournir le constructeur de déplacement et l'opérateur d'affectation de déplacement :
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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn