あることをするために、検索して見つけたページに書いてあったコード。
try{
// [2] OLE初期化
CoInitialize(NULL);
// [3] IShellLinkインターフェイスの作成
hr = CoCreateInstance(...);
if (hr != S_OK)
throw(FALSE);
...
throw(TRUE); // 成功
}
catch(BOOL IsOK)
{
// [7][8] オブジェクト解放
...
// [9] OLE終了処理
CoUninitialize();
if (!IsOK){
MessageBox(...);
}
return IsOK;
}
やめてよ、こんな無意味な try - throw - catch の使い方。。。
まぁ、ね。C++ には(Microsoft 拡張があるけど)finally が無いので、仕方ないところもあるけど。まぁ、ね。2000年に書かれたページなので、その頃には Microsoft 拡張もなかったのかもしれないけど。
それでも、最後の throw(TRUE) ってなにさ?!
ここでやってることって、「ある実行ブロックの最後に、必ず実行したいコードがある。そのブロックでは、特定の条件によっては途中でブロック内の他のコードを実行できなくなることがある。」ってことですよね。BOOL しか受けていないので、その他の例外が発生することは考えていない、あるいは、その他の例外が発生しないことを調査済みであると考えられます。だからこそ、無意味なのです。
単純に考えるなら、if をネストします。ただ、ネストが深くなるのを嫌ったのでしょう。次に考えるのは、関数に切り出すことです。関数に切り出すことで増加する、呼び出しのオーバーヘッドを避けたかった?inline を知らない?throw のコストを知らない?
こんな使い方するなら、goto 使えばええやん。。。
{
// [2] OLE初期化
CoInitialize(NULL);
// [3] IShellLinkインターフェイスの作成
hr = CoCreateInstance(...);
if (hr != S_OK)
goto atoshimatsu;
...
hr = S_OK;
}
atoshimatsu:
{ // 実行したいブロックを明確化するためのブラケット
// [7][8] オブジェクト解放
...
// [9] OLE終了処理
CoUninitialize();
} // atoshimatsu
if (!hr){
MessageBox(...);
}
return hr;
単に下に流すだけなら、do - while ループを使う方法もある。(C#3.0 なんかの匿名関数って、こういうことにも使えるのかな?)
do { // 実行範囲をブロック化したいためのループ
// [2] OLE初期化
CoInitialize(NULL);
// [3] IShellLinkインターフェイスの作成
hr = CoCreateInstance(...);
if (hr != S_OK)
break;
...
hr = S_OK;
} while (FALSE);
// [7][8] オブジェクト解放
...
// [9] OLE終了処理
CoUninitialize();
if (!hr){
MessageBox(...);
}
return hr;
なんにしても、ここで try - catch をしなければならない理由はない。この使い方なら、goto 文と変わらない。だったら、goto の方が読みやすいと思う。
goto 文が、なぜ嫌われるのか。それは、実行の流れがそこで別のところへ移動するから、であるはず。これを突き詰めて考えていくと、while や、for でさえも、ループの最後では実行の流れを最初に戻している。if 文にしても、条件が成立しなければブロックの次のステートメントまで飛んでいる。つまり、単に実行の流れが別のところ(次のステーメント以外)へ移動することが嫌われているわけではない。
じゃぁ、何が嫌われるのか。あるいは、何ができてしまうことが悪とされるのか。この、「悪とされること」を避ければ、別に使ったってええんちゃうん?
『C# 言語リファレンス』では、「ジャンプ ステートメント」として、break, continue, return, throw と並べて紹介されていますね。『C++ Language Reference』には、throw が入っていません。
また、VS2005 で確認していますが、C 言語にも、Microsoft Specific で try - finally ステートメントが拡張定義されています。積極的に利用しましょう。
投稿日時 : 2007年9月27日 21:44