今回は例外を投げる場所を変えてみたいと思います。どこからでも投げていたようですが、「ここ」から投げるとどうなるのでしょうか?
では、今回の要点です。
では、いってみましょう。
今まで例外を投げてきたのは、try ブロック内と、特に何もない場所だけでした。今回は catch ブロック内から例外を投げることを考えてみましょう。
特に何もない場所で例外を投げる関数を catch ブロックから呼ぶことはできそうです。ということは、catch ブロックから例外を投げることはできそうですね。
しかし、その例外はどこでキャッチされるのでしょうか? 同じ try ブロックについている catch ブロックでしょうか? それとも、その外の try ブロックについている catch ブロックでしょうか? では、早速試してみましょう。
プログラム |
---|
// Except3.cpp #include <iostream.h> void Func() { try { throw 1; } catch(int nError) { throw "Error"; } catch(char* str) { // こっちでキャッチされるかな? cout << "Func : " << str << endl; } } int main() { try { Func(); } catch(char* str) { // それともこっちかな? cout << "main : " << str << endl; } return 0; } |
実行結果 |
main : Error |
無事、catch ブロックから例外を投げることができました。そして、catch ブロックから例外を投げても、その catch ブロックと同じ try についている catch ブロックではキャッチされませんでした。
例外はその try-catch ブロックの外、つまり main にある catch ブロックでキャッチされます。このように、例外は catch ブロックからなら、さらに外の try-catch ブロックに対して投げることができるというわけです。
しかし、エラー処理でエラーが出るのはともかくとして、そのエラーの処理を外に任すというのもまた変な話です。そういう場合は catch ブロック内にまた try-catch ブロックを作ってやることになると思います。
それよりは、同じ例外をもう1度投げることの方が多いと思います。その関数内でのエラー処理をして、それからその例外を外にも通知するというわけです。
つまり、こういう感じです。
// Except4.cpp #include <iostream.h> void Func() { char* buf1 = NULL; char* buf2 = NULL; try { buf1 = new char[0x7FFFFFFF]; if(buf1 == NULL) throw 1; buf2 = new char[0x7FFFFFFF]; if(buf2 == NULL) throw 2; } catch(int fError) { switch(fError) { case 2: delete [] buf1; } throw fError; } delete [] buf1; delete [] buf2; } int main() { try { Func(); } catch(int fError) { cout << "エラー終了しました。エラーコード " << fError << endl; } return 0; } |
このように、例外が発生したことを外に知らせたいけど、内部でも終了処理が必要だ、というときがあるということです。こういうときは、おそらく同じ例外を投げることになるでしょう。
このような場合を想定して、実は同じ例外を投げるときは特別な文法が存在します。
// Except4b.cpp #include <iostream.h> void Func() { char* buf1 = NULL; char* buf2 = NULL; try { buf1 = new char[0x7FFFFFFF]; if(buf1 == NULL) throw 1; buf2 = new char[0x7FFFFFFF]; if(buf2 == NULL) throw 2; } catch(int fError) { switch(fError) { case 2: delete [] buf1; } throw; } delete [] buf1; delete [] buf2; } int main() { try { Func(); } catch(int fError) { cout << "エラー終了しました。エラーコード " << fError << endl; } return 0; } |
何と、throw 文に値を渡していません。こうすると、今処理している例外と同じ例外を投げます。簡単ですね。
例外処理に入ってから、何か異様に一章が短い気がします。次はもうちょっと長めにしてみましょうか。
それはともかく、今回の要点です。
それでは、次回まで。
Last update was done on 2001.3.3
この講座の著作権はロベールが保有しています