在GC语言中是否有关于(或更好地使用)RAII的研究?

时间:2010-09-10 15:14:37

标签: garbage-collection using-statement raii with-statement object-lifetime

注意:对象生命周期RAII不使用/与块范围RAII

似乎可以使用额外的gc类别,短期对象(经常检查gc类别),长期存在的对象(不常检查gc类别)和资源对象(非常频繁地检查gc类别)。或者可能使用额外的引用来计算资源对象的gc。

似乎使用/ with style可以通过促进I / O阻止大量I / O传播的更多功能样式(原谅我,如果我错了,这不是功能样式)可以带来一些好处基于对象的RAII的地方与灵活性(因为它更容易)。但是一些问题可能需要很难跟踪资源的生命周期。

除了避免gc的复杂性和速度之外还有其他原因吗?主流语言没有这样做吗?(我知道有些语言在其主要实现中使用引用计数作为gc的一部分,因此,RAII可能在那里工作,但是因为我认为他们的规范没有为某些类型的对象/或所有对象指定引用计数,并且人们使用的其他实现没有引用计数,因此限制在这些语言中使用对象生存期RAII。

P.S。:他们在perl中有c ++类型的RAII吗?

1 个答案:

答案 0 :(得分:4)

许多语言使编写自定义内部块处理器比传统的C ++更容易(这可能已在最新标准的当前草案中得到解决)。当你拥有这些时,使用RAII进行精确资源处理的大部分要求变得更加紧迫;你可以这样做:

using (Transaction t = makeTX()) {
    // blah
}

而不是:

{
    Transaction t = makeTX();
    // blah
}

除了当你有多个嵌套的using结构时,资源释放的顺序更清楚,所以没有太大的区别。 (在抛出异常的情况下,IMO也更容易进行特殊处理,对于像你想要回滚错误的交易一样有用,但我不希望每个人都同意我的意见。)另请注意有许多不同的方式来编写using构造,有些方法比其他方法更重要,但我们并不需要在这里探索差异。

鉴于以这种不同的方式处理确切的资源处理,对C ++ RAII样式的需求要少得多,并且使用垃圾收集(GC)是可行的,因为它处理复杂的情况(即,它处理它的任何地方)很难将对象生命周期与特定范围联系起来。公平地说,在某些情况下,您需要精确的资源管理并且具有非平凡的生命周期,但这些案例对每个人来说都是讨厌的

Perl使用垃圾收集并且具有廉价的子程序块,大多数其他脚本语言也是如此(因为代码和数据之间的划分在脚本语言中比在更传统的编译语言中更松散)。我所知道的唯一不使用GC的大型脚本语言是Tcl,这是因为由于技术语义原因,保证了价值系统无循环,因此引用计数就足够了。尽管如此,代码块仍然非常便宜。

如果我们看一下主流编译语言(即不是脚本语言),那么我们在1990年左右就会看到一个鸿沟。之前的语言(包括C ++)往往不会假设垃圾收集(有一些例外,如Lisp,Smalltalk和函数式编程语言)而在那之后的语言(特别是Java和C#)假设GC。我想在这一点上有一个重大的哲学转变,可能与在此之前处理GC中最令人震惊的问题的一些聪明的实现相结合。当你有GC时,你根本不认为RAI​​I是一个解决方案;它根植于C ++的世界模型。


我刚刚完成了这个术语。