C++のイディオムに、RAII (Resource Acquisition Is Initialization) というものがある。これはコンストラクタ内で資源確保を行うことにより、オブジェクトが利用するリソースを所有することを強く主張するものであり、巷のC++プログラムの随所で見られる技法である。
Initializationという単語が出てくるので、ぱっと見コンストラクタにしか関連しないイディオムのようだが、実際にはデストラクタ内で、確保したリソースを確実に、予測可能なタイミングで解放することも含んでいる。
実は、C++で一番重宝するのが、この「リソースの予測可能なタイミングでの確実な解放」であったりする。「リソースの確実な解放」というとGCが思い浮かぶが、GCは基本的にメモリ管理を行うための手法であり、メモリはリソースの一番分かりやすい例でしかない。
GCでは困難なリソース管理の例として、JavaにおけるDBへのコネクション管理がある。Javaにおいて、DBへの接続、問い合わせ、切断という一連の工程を記述する場合、典型的には try catch finally を用いる。try節の冒頭でコネクションオブジェクトを構築し、finally節でコネクションオブジェクトのclose()メソッドを呼び出すことにより、リソースを解放するものである。オブジェクト指向的な考え方をするなら、コネクションオブジェクトの寿命とDBへの物理接続期間は一致すべきである。しかしJavaではオブジェクトの消滅タイミングが予測できないため、明示的に close()を呼び出して物理接続を閉じざるを得ない。これでは万が一finallyを書き忘れたら、物理接続が残留してしまう。第一美しくない。
C++なら、コンストラクタでコネクション確保、デストラクタでコネクション解放を行うクラスを作成し、自動変数を用いてオブジェクトを構築すればよい。そうすれば、変数がスコープアウトした時点で確実にコネクションが解放される。この方法ではオブジェクトが物理接続を「所有している」ことが明確であり、またスコープにより物理接続の終了タイミングを完全に制御できる。実にエレガントである。
| | 2005-09-23 11:49