C RAII クラスの OpenGL オブジェクト: 落とし穴と解決策
C RAII クラスでは、オブジェクトがスコープ外になるとメンバーが自動的に解放されますリソースの割り当て解除を確実に行うため。ただし、このようなクラスで OpenGL オブジェクトを扱う場合、意図しない結果が生じる可能性があります。
次のコードを考えてみましょう。
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } // Other members };
このクラスは OpenGL バッファ オブジェクトを管理します。このオブジェクトは、デストラクター。ただし、これらのオブジェクトをコピーまたは移動構築しようとすると、予期しないエラーが発生します。
この問題は、明示的なコピーまたは移動コンストラクター/代入演算子が不足していることが原因で発生します。コンパイラによって生成されたコピー コンストラクターはメンバー変数をコピーするだけで、同じ OpenGL バッファ オブジェクトを共有する 2 つのオブジェクトが生成されます。一方のオブジェクトが破棄されると、もう一方のオブジェクトも無効になり、エラーが発生します。
同様に、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 中国語 Web サイトの他の関連記事を参照してください。