質問としてこれを投稿してくれてありがとう。:)
私はそのデストラクタと言って、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を使用することは理にかなっています。
言い換えると、どちらかをシミュレートするためにどちらかを使用できるからといって、両方が1つの同じ問題であること、または両方が両方の問題の適切な解決策であることを意味しません。