首页 > 后端开发 > C++ > 正文

为什么 C RAII 类中的 OpenGL 对象在复制后停止工作?

Barbara Streisand
发布: 2024-11-26 19:14:09
原创
575 人浏览过

Why Do My OpenGL Objects in C   RAII Classes Stop Working After Copying?

C RAII 类中的 OpenGL 对象:为什么它们在复制后停止工作

在 C 中,通常使用 RAII(资源获取即初始化) )以确保对象在破坏时自动清理。然而,在处理 OpenGL 对象时,了解 RAII 模式如何影响对象使用至关重要。

考虑以下封装 OpenGL 缓冲区对象的类:

class BufferObject {
private:
  GLuint buff_;

public:
  BufferObject() { glGenBuffers(1, &buff_); }
  ~BufferObject() { glDeleteBuffers(1, &buff_); }
登录后复制

最初,该类似乎运行正常。但是,在执行某些操作时会出现问题:

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.
登录后复制

通过push_back或return语句复制类会导致意外的OpenGL错误。要理解原因,有必要深入研究 RAII 的机制。

复制对象时,会调用默认的复制构造函数(假设存在)。在这种情况下,默认的复制构造函数只是复制成员变量。但是,此副本包含 OpenGL 对象句柄 (buff_),该句柄对于每个对象都是唯一的。

当原始对象被销毁时(在我们示例中的第一个范围的末尾),就会出现问题。析构函数尝试删除已被新对象复制的 OpenGL 对象。这个孤立的 OpenGL 对象无法再使用并导致错误。

要解决此问题,为 OpenGL 对象包装器定义自定义复制和移动语义至关重要。这种方法可确保 OpenGL 对象引用在对象之间正确传输,而不会引起冲突。

移动对象涉及将其资源的所有权转移到另一个对象。对象的资源不是复制,而是分配给新对象,并且原始对象保持有效但为空的状态。这种方法可以防止潜在的冲突并确保 OpenGL 对象保持有效。

在下面修改后的 BufferObject 类中,删除了复制构造函数和复制赋值运算符,并实现了移动语义:

class BufferObject {
private:
  GLuint buff_;

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

  BufferObject(const BufferObject& other) = delete;
  BufferObject& operator=(const BufferObject& other) = 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;
  }

  ~BufferObject() { Release(); }

  void Release() {
    if (buff_)
      glDeleteBuffers(1, &buff_);
  }
};
登录后复制

通过实现移动语义,可以为 OpenGL 对象创建仅移动的 RAII 包装器。这种方法可以安全高效地处理 C 中的 OpenGL 对象。

以上是为什么 C RAII 类中的 OpenGL 对象在复制后停止工作?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板