自分の状況でRAIIを最大限に活用する方法がわかりません。これは状況です:
基本的なレンダラーを作成しています。Geometryは、頂点が追加されている可能性のあるGeometryクラスによって記述されます。Geometryオブジェクトをレンダリングに使用するには、最初にコンパイルする必要があります(つまり、Geometry用にVBOが作成されます)。ジオメトリオブジェクトのコンパイル(および逆コンパイル)は、レンダラーオブジェクトを介して実行されます。逆コンパイルは、ジオメトリオブジェクトの処理が完了したら実行する必要があります。逆コンパイルを行わないと、メモリリークが発生します。
これが私が説明していることの例です:
Renderer renderer; // the renderer object
{
Geometry geometry;
// add vertices
// and play around with material, etc.
if(!renderer.compile(geometery); // compile the geometery, so we can use it
{
cerr << "Failed to compile geometry!\n";
}
// now we can use it...
renderer.render(geometry, RenderType::TriangleStrips);
} // if I don't call renderer.decompile(geometry) here, I will get a leak
私がやろうとしているのは、レンダラーに逆コンパイルするように明示的に指示せずに、ジオメトリを逆コンパイルすることです。これは、単にメモリリークを減らすためです。私が最初に考えたのはRAIIを使用することでしたが、そうすると、GeometryクラスにはRendererクラスが必要になり、かなり面倒に見えます。ジオメトリをコンパイルしたRendererオブジェクトへの参照が必要になるためです。
私が考えたもう1つの方法は、レンダラーにジオメトリを作成させることでしたが、これにより、ジオメトリオブジェクトが動的に(つまり、newで)割り当てられ、非常に面倒に見えます。
また、一意のハンドルオブジェクトへのunique_ptrなど、ジオメトリ内にハンドルオブジェクトを配置することも考えました。
例えば
class GeometeryHandle
{
virtual ~GeometeryHandle() = 0;
};
GLuint
ハンドル内に格納するためにも使用される可能性があるため、実際に機能する可能性があります。ただし、レンダラー参照を介してジオメトリを直接逆コンパイルできるため、これが適切かどうかはわかりません。つまり、デストラクタを介して直接呼び出す場合も同じことを行います。
誤ってジオメトリを逆コンパイルしないように、これを適切に設計するにはどうすればよいですか?