首页 >后端开发 >C++ >如何安全管理 C RAII 类中的 OpenGL 对象?

如何安全管理 C RAII 类中的 OpenGL 对象?

Susan Sarandon
Susan Sarandon原创
2024-11-25 10:52:11495浏览

How Can I Safely Manage OpenGL Objects within C   RAII Classes?

C RAII 类中的 OpenGL 对象:陷阱和解决方案

在 C RAII 类中,当对象超出范围时,成员会自动释放以确保资源重新分配。然而,在此类中处理 OpenGL 对象时,可能会出现意想不到的后果。

考虑以下代码:

class BufferObject
{
private:
  GLuint buff_;

public:
  BufferObject() { glGenBuffers(1, &buff_); }
  ~BufferObject() { glDeleteBuffers(1, &buff_); }
  // Other members
};

此类管理一个 OpenGL 缓冲区对象,应在析构函数。但是,当尝试复制或移动构造这些对象时,会发生意外错误。

问题源于缺乏显式复制或移动构造函数/赋值运算符。编译器生成的复制构造函数只是复制成员变量,导致两个对象共享同一个 OpenGL 缓冲区对象。当一个对象被销毁时,另一个对象就会失效,从而导致错误。

同样,InitBuffer函数:

BufferObject InitBuffer()
{
  BufferObject buff;
  // Do stuff with `buff`
  return buff;
}

也会失败,因为buff被复制到返回值后被销毁。

为了解决这些陷阱,应该使用仅移动类型。在 C 中,这意味着删除复制构造函数和复制赋值运算符,同时提供转移所有权的移动等效项:

class BufferObject
{
private:
  GLuint buff_;

public:
  BufferObject() { glGenBuffers(1, &buff_); }
  BufferObject(const BufferObject&) = delete; // no copy constructor
  BufferObject& operator=(const BufferObject&) = delete; // no copy assignment

  BufferObject(BufferObject&& other) : buff_(other.buff_) { other.buff_ = 0; }
  BufferObject& operator=(BufferObject&& other)
  {
    if(this != &other)
    {
      Release(); // release current resource
      buff_ = other.buff_;
      other.buff_ = 0;
    }
    return *this;
  }
  ~BufferObject() { Release(); }
  void Release() { if(buff_) glDeleteBuffers(1, &buff_); }
  // Other members
};

通过这些更改,复制和移动 BufferObject 实例变得安全,并且 OpenGL 资源可以在RAII 模式。

以上是如何安全管理 C RAII 类中的 OpenGL 对象?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn