RAII
RAII（）は、日本語では「リソース取得は初期化である」「リソースの確保は初期化時に」「リソースの取得と初期化」などの意味を持ち、資源（リソース）の確保と解放を、クラス型の変数の初期化と破棄処理に結び付けるというプログラミングのテクニックである。特にC++とD言語で一般的であり、デストラクタをサポートしないC言語などに対する優位性や利便性のうちのひとつとなっている。
RAIIでは、資源の取得をクラス型変数の構築（初期化）時に、また返却を破壊時に行う。自動変数がスコープを離れるときデストラクタが呼ばれるため、クラス型変数の寿命が終わるとすぐに資源が返却されることが保証できるようになる。これは例外が発生したときでも同様であるため、RAIIは例外安全なコードを書くための鍵となる概念となった (Sutter 1999)。
RAIIの最も基本的な活用例は、動的確保されたメモリを自動解放するスマートポインタ (smart pointer) である。C++においてnew演算子（またはnew[]演算子）で動的に確保されたメモリは、不要になったときにその領域を指すポインタを経由してdelete演算子（またはdelete[]演算子）で明示的に解放しなければならない。もし解放忘れがあるとメモリリークにつながるが、解放忘れがないように細心の注意を払って、コードパスに手動でひとつひとつ削除処理を記述していくことは非常に手間がかかる。一方、C++ではオブジェクトをスタックに割り当てることも可能であり、動的確保されたメモリを指すポインタをラップするスマートポインタクラスのオブジェクトをスタックに割り当て、ラッパーオブジェクトの寿命が尽きた時点で自動的に呼び出されるデストラクタを利用することにより、動的確保されたメモリの解放を明示的に逐一記述することなく、暗黙的かつ確実に実行させることができる。標準C++ライブラリにおける動的配列クラステンプレートのcodice_1なども、プログラマが明示的にnew[]およびdelete[]を呼び出す必要のないRAIIクラスの一種である。
RAIIはファイル操作にも用いられる。C言語ではファイルアクセスの際、codice_2関数により取得したcodice_3オブジェクトを明示的にcodice_4関数で解放することでファイルを閉じる必要があったが、標準C++ライブラリのファイルストリームでは、オブジェクトのコンストラクタでファイルストリームを開き、デストラクタで閉じることで、ファイルハンドルの管理を自動化し、リソースリークを防ぐことができる。このようなファイルアクセスの管理に限らず、C++のスコープ機構はあらゆるリソースの寿命管理に活用できる。ほかには、マルチスレッドアプリケーションにおいてクリティカルセクションのロックの管理にもよく用いられる。C++03規格以前においても、Boost C++ライブラリやMicrosoft Foundation Classライブラリなどにクリティカルセクション管理用のRAIIクラスが用意されていたが、C++11規格でスレッドおよび同期オブジェクトが標準化された際に、類似のRAIIクラスがcodice_5およびcodice_6として導入された。
また、動的に確保されたメモリの所有権もRAIIで管理できる。所有権が唯一となるスマートポインタクラステンプレートとして、C++03までの標準C++ライブラリではcodice_7が用意されていたが、C++11以降では非推奨となり、代替のcodice_8が用意されている。Boost C++ライブラリには類似のクラステンプレートとしてcodice_9やcodice_10が実装されている。また、参照カウント方式で所有権を共有するオブジェクトのスマートポインタクラステンプレートとして、Boost C++ライブラリのcodice_11がある。これはC++11にてcodice_12として標準化された。codice_13とともに利用する弱参照スマートポインタとして、それぞれcodice_14およびcodice_15が存在する。そのほか、侵入型参照カウント方式のcodice_16、のポリシーベースのcodice_17、COMインターフェイスオブジェクト (codice_18) の参照カウント管理に特化したATLのcodice_19などがある。
後の例のようにRAIIは例外安全の達成にも活用される。RAIIを使えばあちこちにcodice_20-codice_21ブロックを記述することなくメモリリークやリソースリークを防げる。
以下、特に断りがない限り、C++03以前でもC++11以降でもコンパイルできるコードで例示する。
単純な例として、関数内で一時的な作業領域として配列を動的確保することを考える。単純な方法では、以下のようにnew[]演算子を使用する。
これはC言語のmallocおよびfree関数による原始的な寿命管理手法に近い。もし動的に確保したメモリを削除する前に関数を抜けるとメモリリークしてしまうため、慎重に削除処理をひとつひとつ記述していく必要がある。動的にメモリ管理するオブジェクトの数が増えるにつれ、ソースコードのメンテナンスコストは増大していく。
一方、RAIIを利用した場合は以下のようになる。
Boost C++ライブラリのcodice_22を使う場合は以下のように書ける。
C++11以降のcodice_8を使う場合は以下のように書ける。
RAIIを使ってメモリ管理する場合、明示的な削除処理の記述が必要なくなり、コードの見通しやメンテナンス性が向上する。関数の途中でreturnしたり、例外がスローされたりする場合でも、後始末を自動的に実行してくれる。また、C++のテンプレートを利用することで、任意の型に対するRAIIを実現するラッパークラスを定義することができる。C++の標準テンプレートライブラリ (STL) には、RAIIの概念をもとに実装された汎用的な動的配列のクラステンプレートとして、codice_1が用意されている。
別の例として、ファイルのオープンとクローズを挙げる。従来の標準Cライブラリを使って、直接リソースを管理する書き方だと以下のようになる。
一方、RAIIを利用した場合は以下のようになる。
標準C++ライブラリでは、抽象化されたファイルストリーム管理用のRAIIクラスとして、codice_25が用意されている。
codice_26クラスではcodice_27をカプセル化したが、RAIIの真髄は有限の資源ならば何でも同様に管理できることにある。そしてRAIIでは、関数（やその他ブロック）を抜けるときに適切に資源が破棄されることが保証される。なお、codice_26クラスのコンストラクタはファイルが開けなければ例外を投げるため、インスタンスが生成されていれば内包するファイルハンドルは常に利用可能であると仮定してよい。
RAIIを使わない場合、例外が発生するとある問題が生じる。複数の資源を確保する際、それぞれの確保の間に例外が投げられたら、codice_21ブロックではどれを解放すべきか分からなくなってしまう（通常、確保されていない資源を解放することはできない）。codice_30やcodice_31のように、初期値を無効と見なすことにして二段階初期化したり、codice_20-codice_21ブロックを重ねていったりするなど、状況に応じてコードを適切に書いていかなければ安全性は得られない。codice_34やcodice_35のようなRAIIならばこれにも対処できる。変数（メンバ変数も含む）が構築されたときとは逆順で破棄され、また完全に構築された（内部で例外が投げられずにコンストラクタが実行された）オブジェクトのみが破棄されるので問題は起こらない。これはプログラムが資源（またはそれに類するもの）の管理から逃れることができるようになったということである。RAIIクラスを定義する手間はかかるが、いくつもの関数でRAIIクラスを使っていれば、コードの再利用により全体的にはコードが単純化し、良いプログラムにする手助けとなる。また、副次効果としてビジネスロジックの記述に集中することができるようになる。
なお、codice_30やcodice_31はJavaのようなRAIIでない言語での資源管理に使われるイディオムに似ている。Javaのcodice_20-codice_39ブロックは資源の確実な返却を実行するポイントを提供するが、都度codice_20-codice_39ブロックで適切に破棄処理を書かなければならず、プログラマに負担がかかる。
スマートポインタと呼ばれる類のクラスを使い、RAIIを任意のリソース管理APIへ適用することも可能である。
なお、この節では広い意味でスマートポインタという言葉を使っている。一般的にはメモリに特化したものをスマートポインタと言う。
例えば、codice_42は、（codice_43を含む）任意の型の解放関数を受け付け、またcodice_44でない広義の「ヌル」値（無効値）も受け付ける（Windowsのように複数の呼出規約が用いられる環境では、どんなものでも受け付ける）。
以下はWindows APIのファイル入出力関数およびWinsock API関数のリソースをRAIIでラップした例である。codice_45関数が返す無効値codice_46およびcodice_47関数が返す無効値codice_48は、Windows SDK 8.1ではそれぞれ以下のように定義されている。
RAIIは特に複数のリソースを同時に管理する場合に効果を発揮する。少なくともcodice_49節がいくつも現れて混乱する事態からは逃れられる。
RAIIクラスでは解放関数が失敗すると問題になる。C++では言語の制約上デストラクタから例外を投げるのは良い考えではないため、デストラクタではすべての例外を握りつぶす必要がある。エラーコードによる通知も難しくなるため、結果として解放失敗の原因を上位層に通知することが難しくなる。そのためcodice_42のようなクラスは、次のどちらかに当てはまるときには使うべきではない。
RubyとSmalltalkは特別なスコープに関連付けられた変数の中にあるクロージャブロックという形でRAIIに対応している。以下はRubyの例である。
C#とVB .NET 2005はC++デストラクタに代わるcodice_51インターフェイスを実装するクラスとcodice_52文を使ってRAIIに似た機能を実現している。
Python 2.5に追加されたcodice_53ステートメントでは、同様の目的にcodice_54とcodice_55のメソッドを使う。
Javaはバージョン7で導入されたtry-with-resources文により、C#のusing文に近い機能を提供する。