在Java和C#等语言中,有一个"析构函数"的概念。 RAII如何与这一概念正交,如何在这些语言中实现?
答案 0 :(得分:7)
最大的区别是调用终结器/析构函数时。对于RAII,当变量超出范围时,它总是被调用,它具有一定的保证时间。使用垃圾收集,在系统确定对象不再使用后随时调用它。
从概念上讲,垃圾收集是具有无限生命周期的对象的实现细节。就您的程序而言,GC对象始终存在。这就是为什么它没有被收集,直到没有更多的参考,所以程序永远不需要知道它被收集。终结者是这个小说中的一个小漏洞,但它们仍然受制于一些规则:你不知道什么时候会被召唤。你甚至不知道/他们是否会被召唤。
您可以在D中并排看到差异.D中的struct析构函数为您提供RAII。类析构函数与垃圾收集一起使用。 (大多数情况下,你也可以调整它们,它们并不是一个很难的规则。)
类析构函数:
除非成员是类中的值类型,否则无法引用成员。 GC可能已经收集了它们,因为在析构函数运行时,该类已经/已经/被认为已经死亡。
无法运行,直到在内存压力下请求分配,触发GC收集扫描。它可能永远不会运行。
只有在特殊情况下它才能替代RAII。 RAII的保证允许您在稀缺资源的情况下使用它。
答案 1 :(得分:3)
在没有它的语言中替换RAII是try-finally。它保证即使抛出异常也会调用finally中的清理代码。拉动插头时它不会工作但是你有不同的问题。
没有尝试 - 最后你必须非常小心,所有代码路径都将进行适当的清理,这远非琐碎的路径