在这种情况下,我不知道如何才能充分利用RAII。情况是这样的:
我正在创建一个基本的渲染器。几何图形由Geometry类描述,该类可能添加了顶点。为了使Geometry对象用于渲染,必须首先编译它(即,将为Geometry创建一个VBO )。geometery对象的合并(和解压)是通过Renderer对象完成的,反编译必须在geometery对象完成后才能完成。如果不做反编译,就会有内存泄漏。
下面是我所描述的一个例子:
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对象的引用,该对象编译了geometery。
我想到的另一种选择是让渲染器创建几何图形,但这将导致几何对象动态分配(即使用new),而且看起来也很混乱。
我还考虑在几何图形中放置一个句柄对象,例如指向抽象句柄对象的unique_ptr。
例如:
class GeometeryHandle
{
virtual ~GeometeryHandle() = 0;
};这实际上可能会起作用,因为它还可以用于在句柄内存储GLuint。我不确定这是否合适,因为我可以直接通过渲染器引用来反编译几何图形。也就是说,如果我直接通过析构函数调用它,它也会做同样的事情。
我应该如何恰当地设计它,这样我才不会意外地没有反编译几何图形?
发布于 2013-02-24 21:08:46
RAII要求dstructor执行“撤销”操作。
在这种情况下,几何体被破坏,但渲染仍然存在。你唯一的触发器是Geometry析构函数,它应该知道render编译了什么,来调用他进行反编译。
但是,由于了解rederes并不是几何的目的,您很可能需要一个助手类(让我们称之为Compile_guard),它应该在几何完成后立即实例化,将geometry和Render作为参数,并在构造时调用Render::compile,在销毁时调用Render::反编译:
Renderer renderer; // the renderer object
{
Geometry geometry;
// add vertices
// and play around with material, etc.
Compile_guard guard(render, geometry);
if(!guard); // Invalid compilation ....
{
cerr << "Failed to compile geometry!\n";
return; // this is exception safe!
}
// now we can use it...
renderer.render(geometry, RenderType::TriangleStrips);
} //here guard will decompile关于Compile_guard,它可以是这样的
class Compile_guard
{
public:
Compile_guard(Render& r, Geometry& g) :render(&r), geometry(&g), good(false)
{ good = render->compile(*geometry); }
~Compile_guard()
{ if(good) render->decompile(*geometry); }
explicit operator bool() const { return good; }
Compile_guard(const Compile_guard&) =delete; //just avoid copy and assign.
Compile_guard& operator=(const Compile_guard&) =delete;
private:
Render* render;
Geometry* geometry;
bool good;
};https://stackoverflow.com/questions/15051795
复制相似问题