用D语言释放资源

时间:2012-02-23 10:03:56

标签: d direct3d direct3d11

在c ++中使用Direct3D时我可以编写一个“Cube”类,其中包含一个“ID3D11Buffer * vertexBuffer_”,并确保该Cube对象的析构函数调用vertexBuffer _-> Release()。

我可以有一个包含“unique_ptr cube_”对象的“Scene”类。所以我知道当我删除我的场景时,立方体将被删除,因此将调用它正在使用的D3D资源上的释放。

在D中我无法做到这一点。我可以编写析构函数,但我不知道它们什么时候会被调用。如果GC不需要内存,则可能永远不会被调用...

那么在D中处理这种事情的最佳方法是什么?我可以为每个对象添加一个“Free”成员函数,释放它自己的所有资源,并在它拥有的任何对象上调用“Free”,但这似乎是一个容易出错的手动操作,而且是C ++的后退步骤。

在D中有没有更好的方法来处理这类事情?

2 个答案:

答案 0 :(得分:6)

您可以在堆栈上使用结构。 具有确定性破坏。您甚至可以使用std.typecons.RefCounted对其进行重新计算。如果要保证析构函数运行,请不要在堆上使用结构。目前,我不认为结构体的析构函数如果被放在堆上就会被运行,因为GC没有它需要的信息(应该在它的某个点固定)未来虽然)。

但是如果你坚持把它放在一个类的堆上,并且你想明确地销毁该对象,那么你可以在其上调用clear

clear(obj);

这将调用对象的析构函数然后将其置于无效状态,并且在此之后尝试使用它的任何东西都应该爆炸(IIRC,虚拟表变为零)。但内存实际上并没有被释放。这是GC的工作。并且不要使用delete。它将被弃用。我真的很惊讶它还没有,因为它已被计划多年来摆脱它。

当然,一种选择是使用一个显式函数来调用以释放资源。这是否是一个好主意取决于你在做什么。但无论如何,课程都是由GC收集的,并且无论何时选择都不会被释放。

正在对自定义分配器进行工作,这将为您提供更多如何分配类的选项,其中一个可能允许您对类进行更确定的破坏,但尚未准备好。

如果你感到疯狂,你可以使用std.typecons.scoped,它取代即将被弃用的类型修饰符scope(尽管scope在其他情境中仍然存在 - 例如scope陈述)。它将一个类放在堆栈上。但这是不安全的(这就是scope在此上下文中消失的原因),如果您要将对象粘贴在堆栈上,您可能也可以使用结构。

编辑:您还可以将mallocfreestd.conv.emplace一起使用,将对象放入非GC分配的内存块中,就像您一样有C ++,但我认为你必须显式调用析构函数才能运行它,因为free不了解析构函数(它是一个C函数)。这将有利于使内存与资源一起消失(而在GC堆上的对象上使用clear只会破坏对象的内容,而不是释放内存),但我不知道在GC分配的对象上使用clear购买了很多东西。

但是,您可以创建一个类似于new的免费功能,为您执行mallocemplace,然后拥有类似于delete的免费功能调用析构函数和free,它会给你与C ++相同的情况。事实上,我想知道这是否足以使其成为标准库。这可能是最终会出现在自定义分配器中的事情。因此,如果在不久的将来,您可以使用自定义分配器来执行类似

的操作,那么我一点也不会感到惊讶。
auto obj = customAllocObj.create!MyObj(args);
//Do stuff...
customAllocObj.destroy(obj);

我认为这可以很好地解决你的问题,因为这与你在C ++中的基本相同,只是使用库函数而不是内置new和{{1 }}。我想我会把它提到新闻组。我希望至少有一些人会喜欢这样的功能,这似乎与自定义分配器非常吻合。

答案 1 :(得分:2)

只是为了澄清:析构函数始终被调用。如果在应用程序关闭时尚未最终确定对象,则GC将运行其终结器。

我不知道如何手动调用free()函数来删除顶点缓冲区比在C ++中手动管理内存更容易出错。无论如何,您可能需要查看:http://www.dlang.org/phobos/std_typecons.html#scopedhttp://www.dlang.org/phobos/std_typecons.html#RefCounted