今回は例外を投げる場所を変えてみたいと思います。どこからでも投げていたようですが、「ここ」から投げるとどうなるのでしょうか?
では、今回の要点です。
では、いってみましょう。
今まで例外を投げてきたのは、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
この講座の著作権はロベールが保有しています