プログラミングにおける手法(イディオム)の1つで、リソースの取得と解放を、オブジェクトの初期化と破棄に結びつけることで、リソースの確実な解放を保証します。
特に C++ で重要になっている手法です。
ここでいうリソースとは、メモリ領域やストリームといったものを指しています。リソースの取得とは、メモリアロケーションを行ったり、ストリームをオープンすること、リソースの解放は、デアロケーションや、ストリームをクローズすることを指しています。実際のところ、はじめに何かしら初期化処理を行い、最後に対応する終了処理をおこなうという関係が存在するものは、RAII の考え方ではすべてリソースと捉えられます。
プログラマーには、リソースを適切なタイミングで確実に解放するようにプログラミングする責任があります。しかし、例外が発生する可能性があると、解放処理をすり抜けずに確実に実行するプログラムを書く難易度は高くなり、正しく書けたとしても、ひどく複雑になることがあります。
C++ では、リソースを使用する処理を1つのクラスにまとめ、リソースの取得をコンストラクタで、リソースの解放をデストラクタでおこなう手法があり、これを RAII(Resource Acquisition Is Initialization: 「リソースの取得は初期化」)と呼びます。デストラクタは、オブジェクトが破棄されるときに確実に呼び出される保証があるため、ここにリソースの解放処理を置くことで、例外が発生した場合も含めて、確実に解放処理を実行できます(例外安全)。
リソースの取得をコンストラクタの中でのみおこなうようにするのがシンプルで安全ですが、利便性のために、あとからリソースを再取得できるように、メンバ関数を公開するケースもあります(std::unique_ptr の resetメンバ関数など)。この場合、その関数内でいったん終了処理を行い、取得しなおすように実装します。いずれにしても最後にはデストラクタを通過することになり、最終的に保持していたリソースは確実に解放されます。
C++ の標準ライブラリでも、RAII を活用したクラス(クラステンプレート)が多数存在しており、スマートポインタの unique_ptr や shared_ptr、動的配列の vector などが代表的です。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
![]() |
管理者情報 | プライバシーポリシー |