RAII
スマートポインタと呼ばれる類のクラスを使い、RAIIを任意のリソース管理APIへ適用することも可能である。
なお、この節では広い意味でスマートポインタという言葉を使っている。一般的にはメモリに特化したものをスマートポインタと言う。
例えば、stlsoft::scoped_handleは、(voidを含む)任意の型の解放関数を受け付け、また0でない広義の「ヌル」値(無効値)も受け付ける(Windowsのように複数の呼出規約が用いられる環境では、どんなものでも受け付ける)。
以下はWindows APIのファイル入出力関数およびWinsock API関数のリソースをRAIIでラップした例である。CreateFile()関数が返す無効値INVALID_HANDLE_VALUEおよびWSASocket()関数が返す無効値INVALID_SOCKETは、Windows SDK 8.1ではそれぞれ以下のように定義されている。
RAIIは特に複数のリソースを同時に管理する場合に効果を発揮する。少なくともtry-catch節がいくつも現れて混乱する事態からは逃れられる。
C#とVB .NET 2005はC++デストラクタに代わるSystem.IDisposableインターフェイスを実装するクラスとusing文を使ってRAIIに似た機能を実現している。
Python 2.5に追加されたwithステートメントでは、同様の目的に__enter__と__exit__のメソッドを使う。
Javaはバージョン7で導入されたtry-with-resources文により、C#のusing文に近い機能を提供する。
単純な例として、関数内で一時的な作業領域として配列を動的確保することを考える。単純な方法では、以下のようにnew[]演算子を使用する。
これはC言語のmallocおよびfree関数による原始的な寿命管理手法に近い。もし動的に確保したメモリを削除する前に関数を抜けるとメモリリークしてしまうため、慎重に削除処理をひとつひとつ記述していく必要がある。動的にメモリ管理するオブジェクトの数が増えるにつれ、ソースコードのメンテナンスコストは増大していく。
一方、RAIIを利用した場合は以下のようになる。
Boost C++ライブラリのboost::scoped_arrayを使う場合は以下のように書ける。
C++11以降のstd::unique_ptrを使う場合は以下のように書ける。
RAIIを使ってメモリ管理する場合、明示的な削除処理の記述が必要なくなり、コードの見通しやメンテナンス性が向上する。関数の途中でreturnしたり、例外がスローされたりする場合でも、後始末を自動的に実行してくれる。また、C++のテンプレートを利用することで、任意の型に対するRAIIを実現するラッパークラスを定義することができる。C++の標準テンプレートライブラリ (STL) には、RAIIの概念をもとに実装された汎用的な動的配列のクラステンプレートとして、std::vectorが用意されている。