2012-02-23 58 views
8

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

我可以具有包含“的unique_ptr cube_”对象“场景”类。所以我知道,当我删除我的场景时,多维数据集将被删除,并且因此会调用正在使用的D3D资源的发布。

在D我不能这样做。我可以编写析构函数,但我不知道何时会被调用。如果GC不要求他们可能永远不会被称为记忆...

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

D有没有更好的方法来处理这种事情?

回答

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++中的一样,只是使用库函数而不是内置的newdelete。我想我会在新闻组上提出来。我预计至少有一些人会喜欢这样的功能,而且这似乎很适合自定义分配器。

+0

谢谢您的全面回答! 我不确定我可以在栈上使用一个结构体,因为我的对象的生命周期比它长。明确可能适用于我,但它与我自己的clear()函数似乎没有什么不同。 Ypu've给了我更多的东西要考虑:) – jcoder 2012-02-23 11:25:33

+0

@JohnB我假设你可能会传递结构,但它肯定是真的,这可能无法正常工作,这取决于你的情况。如果你自己做了一些函数,我建议不要在其中调用析构函数 - 这只是要求麻烦(尽管析构函数可以调用任何可以释放资源的函数)。所以,如果你真的想调用析构函数,那么使用'clear'。如果你想要做的只是释放资源,那么专门调用另一个函数可能更有意义,而不是销毁该对象。这取决于你的代码。 – 2012-02-23 18:59:46

2

只是为了澄清:析构函数是总是调用。如果一个对象在应用程序关闭时尚未完成,GC将运行其终结器。

我看不出如何手动调用free()函数来删除顶点缓冲器是任何更多的错误比具有在C手动管理存储器++容易发生。无论如何,你可能想看看:http://www.dlang.org/phobos/std_typecons.html#scopedhttp://www.dlang.org/phobos/std_typecons.html#RefCounted

+2

问题是当内存被释放时会调用析构函数,这将在将来某个时刻GC注意到对象不再被引用时调用。我需要立即释放D3D对象,而不是在将来某个未定义的点处... – jcoder 2012-02-23 10:11:19

+0

['delete'](http://www.d-programming-language.org/expression.html#DeleteExpression)? “如果UnaryExpression是一个类对象引用,并且存在该类的析构函数,则会为该对象实例调用析构函数。” – 2012-02-23 10:27:13

+0

'delete'正在从语言中删除。不要使用它。你可以使用'clear',它将调用对象的析构函数并使对象无效,但它不会释放内存。这是GC的工作。如果你想确定性破坏,那么使用一个结构。 – 2012-02-23 11:03:30