Maison > développement back-end > C++ > Comment RAII avec des objets OpenGL en C peut-il entraîner un comportement inattendu lors de la copie ou du déplacement d'objets ?

Comment RAII avec des objets OpenGL en C peut-il entraîner un comportement inattendu lors de la copie ou du déplacement d'objets ?

Susan Sarandon
Libérer: 2024-11-29 21:12:17
original
693 Les gens l'ont consulté

How Can RAII with OpenGL Objects in C   Lead to Unexpected Behavior When Copying or Moving Objects?

RAII avec les objets OpenGL en C : Comprendre les problèmes cachés

En programmation orientée objet C, l'acquisition de ressources est l'initialisation (RAII) est une technique utilisée pour gérer efficacement les ressources. Lors de l'utilisation d'objets OpenGL dans des classes C, il est courant de vouloir utiliser RAII pour garantir que l'objet OpenGL est correctement libéré lorsque la classe est détruite.

Considérez l'extrait de code suivant :

class BufferObject
{
private:
  GLuint buff_;

public:
  BufferObject()
  {
    glGenBuffers(1, &buff_);
  }

  ~BufferObject()
  {
    glDeleteBuffers(1, &buff_);
  }
};
Copier après la connexion

Cette classe semble implémenter correctement RAII pour les objets OpenGL. Cependant, des problèmes surviennent lorsque la classe est copiée ou déplacée, comme en témoigne le code suivant :

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.
Copier après la connexion

Dans ces scénarios, les objets OpenGL deviennent inutilisables, entraînant des erreurs.

La raison car ce comportement réside dans les constructeurs de copie par défaut et les opérateurs d'affectation générés par le compilateur. Ces opérations copient simplement les membres de l'objet, ce qui entraîne plusieurs objets C référençant le même objet OpenGL sous-jacent. Lorsque l'objet C d'origine est détruit, il libère l'objet OpenGL, obligeant les autres objets à référencer une ressource détruite.

Pour résoudre ce problème, la classe BufferObject doit être de type déplacement uniquement. Cela signifie éliminer le constructeur de copie et l'opérateur d'affectation et fournir des équivalents de déplacement qui transfèrent la propriété de l'objet OpenGL au nouvel objet.

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.
};
Copier après la connexion

Avec ces changements, la classe garantit que l'objet OpenGL est correctement géré et libéré, même lors de la copie ou du déplacement de la classe.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal