RAIIという用語が使用されるときは常に、人々は実際には初期化の代わりに脱構築について話しています。私はそれが何を意味するのかを基本的に理解していると思いますが、よくわかりません。また、C ++は唯一のRAII言語ですか?JavaまたはC#/。NETはどうですか?
RAIIという用語が使用されるときは常に、人々は実際には初期化の代わりに脱構築について話しています。私はそれが何を意味するのかを基本的に理解していると思いますが、よくわかりません。また、C ++は唯一のRAII言語ですか?JavaまたはC#/。NETはどうですか?
回答:
Resource Acquisition Is Initializationは、オブジェクトがそれ自体を完全なパッケージと見なし、他のコードがインスタンスに「ちなみに、すぐにクリーンアップする予定です-今すぐ片付けてください」と伝えることを期待しないことを意味します。通常、デストラクタに意味のあるものがあることを意味します。また、例外をスローするなど、予測が困難な特定の状況ではデストラクタの実行を期待できることを認識して、リソースを管理するためのクラスを作成することも意味します。
Windowsカーソルを待機(砂時計、ドーナツ型の非動作など)カーソルに変更するコードを記述し、作業を行ってから元に戻すコードを記述したいとします。また、「あなたの仕事をする」が例外をスローするかもしれないと言ってください。RAIIの方法は、カーソルが待機するように設定するクラス、希望する処理を実行する「実際の」メソッド、およびカーソルを戻すクラスを作成することです。リソース(この場合はカーソル状態)はオブジェクトのスコープに関連付けられています。リソースを取得すると、オブジェクトを初期化します。例外がスローされた場合、オブジェクトが破壊されることを期待できます。つまり、リソースをクリーンアップすることを期待できます。
RAIIを上手に使用することは、必要ないということですfinally
。もちろん、それは決定論的な破壊に依存していますが、これはJavaではできません。C#およびVB.NETでは、を使用して、一種の決定論的な破壊を取得できますusing
。
RAIIは、オブジェクトのクリーンアップの責任をいつ取るかを部分的に決定します。ルールは、コンストラクタの初期化が完了したときにオブジェクトが責任を負うというルールです。初期化とクリーンアップ、コンストラクターとデストラクターの対称性は、2つが互いに密接な関係にあることを意味します。
RAIIの1つのポイントは、例外の安全性を確保することです。例外がスローされても、アプリケーションは自己整合性を保ちます。一見、これは簡単です-例外がスコープを終了させる場合、そのスコープ内のローカル変数を破棄する必要があります。
しかし、コンストラクター内で例外スローが発生するとどうなりますか?
さて、オブジェクトは完全に構築されていないため、安全に破壊することはできません。コンストラクターは、例外が伝播される前に必要なクリーンアップが行われるように、必要に応じてtryブロックを用意する必要があります。オブジェクトが構築されたスコープの外で例外が伝播すると、オブジェクトはそもそも構築されなかったため、デストラクタ呼び出しはありません。
特に、破棄されるオブジェクト内のメンバーデータのコンストラクターを検討してください。これらのいずれかが例外をスローした場合、メインコンストラクターコードはまったく実行されませんが、そのコンストラクターの暗黙的な部分を形成する一部のコードは実行されます。正常に構築されたメンバーはすべて自動的に破棄されます。構築されなかったメンバー(例外をスローしたメンバーを含む)はそうではありません。
基本的に、RAIIは、特に例外がスローされた場合に、完全に構築されたすべてのものがタイムリーに破壊され、オブジェクトが完全に構築されたかそうでないかを保証するポリシーです。安全にクリーンアップする方法がわからない構築されたオブジェクト)。割り当てられたリソースも解放されます。また、多くの作業は自動化されているため、プログラマーはあまり気にする必要はありません。