很高兴您将其发布为问题。:)
我试图说的是析构函数,并且finally
在概念上是不同的:
- 析构函数用于释放资源(数据)
finally
用于返回到呼叫者(控件)
考虑一下这个假设的伪代码:
try {
bar();
} finally {
logfile.print("bar has exited...");
}
finally
这里完全解决了控制问题,而不是资源管理问题。
出于多种原因,在析构函数中执行此操作是没有意义的:
- 没有东西被“获得”或“创造”
- 无法打印到日志文件不会导致资源泄漏,数据损坏等(假设此处的日志文件未反馈到其他地方的程序中)
logfile.print
失败是合法的,而破坏(在概念上)不能失败
这是另一个示例,这次就像在Javascript中一样:
var mo_document = document, mo;
function observe(mutations) {
mo.disconnect(); // stop observing changes to prevent re-entrance
try {
/* modify stuff */
} finally {
mo.observe(mo_document); // continue observing (conceptually, this can fail)
}
}
mo = new MutationObserver(observe);
return observe();
同样,在以上示例中,没有要释放的资源。
实际上,该finally
区块正在内部获取资源以实现其目标,这有可能失败。因此,使用析构函数(如果Javascript有一个)是没有意义的。
另一方面,在此示例中:
b = get_data();
try {
a.write(b);
} finally {
free(b);
}
finally
正在破坏资源b
。这是一个数据问题。问题不在于将控制权干净地返回给调用方,而在于避免资源泄漏。
失败不是一种选择,并且应该(从概念上)永远不会发生。
每次发行b
都必须与获取配对,因此使用RAII是有意义的。
换句话说,仅因为您可以使用其中一个模拟就不等于既是一个问题,又是同一问题,或者都不是两个问题的适当解决方案。