2008-04-09
まともな内容を書くのは約半年ぶりです。ネタはあっても、"大人の事情"というか、安易にブログに書けないことも多くて大変なのですが、何とか頑張ってみたいと思います。長い間更新していないと、過去に何を書いて、何を書いていないのか、さっぱり分からなくなってしまいますが、気にせずに進めることにします。雑誌でも定期的に同じネタを取り上げますので、それと同じようなものですね。
というわけで、今回はRAII(Resource Acquisition Is Initialization)イディオムです。日本語でいえば、「リソースの獲得は初期化」ということになります。そして、「リソースの解放は終期化」ということでもあります。早い話が、コンストラクタでリソースを獲得し、デストラクタで解放するというイディオムです。
RAIIイディオムの代表例はスマートポインタです。コンストラクタでオブジェクトを生成し、デストラクタで解体します。多くのスマートポインタの実装では、コンストラクタの外で new を使ってオブジェクトを生成し、そのポインタを与えるようになっていますが、気持ちとしてはRAIIということです。
他には、排他制御も分かりやすい例でしょう。コンストラクタでロックをかけ、デストラクタでロックを解除します。途中でエラーが発生して、いきなりリターンしても、例外が送出されても、有効範囲から抜ける際に確実にロックが解除できます。
RAIIイディオムでは、オブジェクトが生成されてから解体されるまでの間、リソースを保持していることが保証されます。ということは、コンストラクタに失敗してリソースが獲得できなかった場合には、例外を送出して、強制的に有効範囲の外に飛び出すようにしなければなりません。
あるいは、生成したオブジェクトへのポインタを返す関数を用意して、リソースの獲得に成功したかどうかを最初に判定する必要があるでしょう。とりあえずオブジェクトを生成して、その後で通常のメンバ関数を呼び出してリソースの獲得を行うのは、もはやRAIIイディオムとはいえません。
実際には例外が使えない状況も多いので、失敗する可能性がある場合にRAIIイディオムを使うのは難しいこともあるでしょう。そこで次回は、例外が使えない環境で、コンストラクタからの例外送出に変わる方法を取り上げてみたいと思います。最近思いついた方法なので、いろいろ穴があると思います。気付いた方は突っ込んでみてください。
Trackback
http://cppemb.blog17.fc2.com/tb.php/107-bf98c6f0
<< old : Next door : New >>
C++と組み込み環境 | Page Top▲
Comment