Heim > Backend-Entwicklung > C++ > Wie kann RAII mit OpenGL-Objekten in C zu unerwartetem Verhalten beim Kopieren oder Verschieben von Objekten führen?

Wie kann RAII mit OpenGL-Objekten in C zu unerwartetem Verhalten beim Kopieren oder Verschieben von Objekten führen?

Susan Sarandon
Freigeben: 2024-11-29 21:12:17
Original
691 Leute haben es durchsucht

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

RAII mit OpenGL-Objekten in C: Versteckte Probleme verstehen

In der objektorientierten C-Programmierung ist die Ressourcenbeschaffung Initialisierung (RAII). eine Technik zur effizienten Verwaltung von Ressourcen. Bei der Verwendung von OpenGL-Objekten innerhalb von C-Klassen ist es üblich, RAII zu verwenden, um sicherzustellen, dass das OpenGL-Objekt korrekt freigegeben wird, wenn die Klasse zerstört wird.

Beachten Sie den folgenden Codeausschnitt:

class BufferObject
{
private:
  GLuint buff_;

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

  ~BufferObject()
  {
    glDeleteBuffers(1, &buff_);
  }
};
Nach dem Login kopieren

Diese Klasse scheint RAII für OpenGL-Objekte korrekt zu implementieren. Beim Kopieren oder Verschieben der Klasse treten jedoch Probleme auf, wie der folgende Code zeigt:

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.
Nach dem Login kopieren

In diesen Szenarien werden die OpenGL-Objekte unbrauchbar, was zu Fehlern führt.

Der Grund Der Grund für dieses Verhalten liegt in den vom Compiler generierten Standardkopierkonstruktoren und Zuweisungsoperatoren. Diese Vorgänge kopieren einfach die Mitglieder des Objekts, was dazu führt, dass mehrere C-Objekte auf dasselbe zugrunde liegende OpenGL-Objekt verweisen. Wenn das ursprüngliche C-Objekt zerstört wird, gibt es das OpenGL-Objekt frei, wodurch die anderen Objekte auf eine zerstörte Ressource verweisen.

Um dieses Problem zu beheben, sollte die BufferObject-Klasse ein Typ sein, der nur verschoben werden kann. Das bedeutet, den Kopierkonstruktor und den Zuweisungsoperator zu eliminieren und Verschiebungsäquivalente bereitzustellen, die den Besitz des OpenGL-Objekts auf das neue Objekt übertragen.

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.
};
Nach dem Login kopieren

Mit diesen Änderungen stellt die Klasse sicher, dass das OpenGL-Objekt korrekt verwaltet und verwaltet wird freigegeben, auch beim Kopieren oder Verschieben der Klasse.

Das obige ist der detaillierte Inhalt vonWie kann RAII mit OpenGL-Objekten in C zu unerwartetem Verhalten beim Kopieren oder Verschieben von Objekten führen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage