用D语言释放资源

jco*_*der 8 direct3d d direct3d11

当在c中使用的Direct3D ++我可以写例如"立方"类,即包含"ID3D11Buffer*vertexBuffer_",并确保该立方体对象的析构调用vertexBuffer _->推出().

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

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

那么在D中处理这类事情的最佳方法是什么?我可以添加一个"免费"的成员函数,每一个释放所有的它自己的资源,并呼吁它拥有的任何对象的"自由"的对象,但是这似乎是一个容易出错的手动操作,并从C++是一种倒退.

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

Jon*_*vis 6

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

但是如果你坚持将它放在一个类的堆中,并且你想要显式地销毁该对象,那么你可以调用clear它:

clear(obj);
Run Code Online (Sandbox Code Playgroud)

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

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

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

如果你感到疯狂,你可以使用std.typecons.scoped,它取代了即将被弃用的类型修饰符scope(尽管scope在其他上下文中仍然存在 - 比如scope语句).它将一个类放在堆栈上.但这是不安全的(这就是为什么scope在这种情况下会消失),如果你要将对象粘在堆栈上,你可能也可能只使用一个结构.

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

但是,你可以再建立类似自由功能new它执行malloc,并emplace为你,再有类似自由函数delete,其调用析构函数和free,这将让你同样的情况C++.事实上,我想知道这是否足以使其成为标准库.这可能是最终会出现在自定义分配器中的事情.所以,如果在不久的将来,你可以使用自定义分配器来做类似的事情,那就不会让我感到惊讶

auto obj = customAllocObj.create!MyObj(args);
//Do stuff...
customAllocObj.destroy(obj);
Run Code Online (Sandbox Code Playgroud)

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