RAII とは Resource Acquisition Is Initialization の略で、リソース管理をオブジェクトの生存期間に結び付ける設計手法である。
基本的な考え方は次のとおりである。
- リソースの確保はコンストラクタ(C++)で行う
- リソースの解放はデストラクタ(C++)で行う
これにより、オブジェクトがスコープを抜けるときに、自動的にリソースが解放される。
リソースとは
ここでいうリソースは、動的に確保したメモリだけではない。
- メモリ
- ファイルハンドル
- ミューテックス
- ソケット
のような、「確保したら必ず後で解放や返却が必要なもの」を広く含む。
例
#include <iostream>
class Resource
{
public:
Resource()
{
std::cout << "acquired\n";
}
~Resource()
{
std::cout << "released\n";
}
};
int main()
{
Resource resource {};
}この例では、resource が作られるときに確保処理が行われ、スコープを抜けるときにデストラクタによって解放処理が行われる。
利点
- 解放忘れを減らしやすい
- 例外で途中脱出しても、スコープを抜けるときに後始末しやすい
- リソース管理の責任をオブジェクトにまとめられる
具体例
現代の C++ では、RAII を手で一から書くより、標準ライブラリの所有者型を使うことが多い。
これらは、オブジェクトが破棄されるときに管理している資源も自動で後始末する。
補足
- RAII は「初期化」という語を含むが、実際には取得と解放の責任をオブジェクトに持たせる設計全体を指す
- 生ポインタに
new/deleteを直接対応させるより、RAII 型に所有させるほうが安全なことが多い