簡単な例として、割り算を行う関数を作ってみることにします。
#include <iostream>
using namespace std;
// 割り算関数
// もしかすると例外を投げる可能性があるかもしれない
int divide(int n1, int n2){
if( n2 == 0 )
throw n2; // 例外を投げる部分
cout << "割り算を実行します" << endl;
return n1 / n2;
}
void main(){
int n1, n2, n3;
cin >> n1 >> n2;
// 例外が起こるかもしれないブロック
try{
n3 = divide(n1, n2);
cout << n1 << " / " << n2 << " = " << n3 << endl;
}
catch( int arg ){
// 例外が起きた場合に処理したいブロック
cout << "余算エラー:" << arg << endl;
}
}
|
C:\>exceptiontest
10 5
割り算を実行しました
10 / 5 = 2
C:\>exceptiontest
10 0
余算エラー:0
C:\>
|
標準入力から数字を2つ読み込み、n1とn2に代入しています。
そして、割り算関数を呼び出すのですが、「try」ブロックで囲んでいますので、
もしかしたら例外が発生するかもしれないことを意味しています。割り算関数の中では、
第二引数が0かどうかをチェックし、0であれば例外を発生させています。
割り算関数では例外をint型で投げていますので、main関数のcatchブロックも
int型のキャッチブロックで処理されます。つまり、「余算エラー」と表示します。
もし、型が異なり(catch(double arg)だった場合)、例外をキャッチできずに異常終了
になります。これでは例外処理機構の意味がなくなってしまうので、必ずキャッチしなければ
なりません。
割り算関数では結果を戻り値として返していますので、もし例外を使わないのであれば、
呼び出し元に割り算を実行できたかどうか通知する手段がありません。これが例外の
便利なところです。
では、チェック自体をしなかったらどうなるでしょうか。これは実行系によって
異なります。昔のコンパイラでコンパイルし、昔のMS-DOSで実行すれば、暴走してしまい、
リセットするしかなくなります。比較的新しいMS-DOSであれば、プログラムが強制終了します。
MS-Windows系でもプログラムが強制終了され、エラーダイアログで通知されます。
このようにプログラム内でエラーを関知して、適当に処理をし、データの保存もしていないのに
プログラムが強制終了されるプログラムはダメなプログラムです。