例外を扱う際に単純な型ではなく、例外用のクラスを作る場合があります。
簡単な例を書きますので、作ってみましょう。
<sample program cpp082-01>
#include <iostream> class MyException { public: void ShowMessage(); }; int main() { try { throw MyException(); } catch (MyException myException) { myException.ShowMessage(); } return 0; } void MyException::ShowMessage() { std::cout << "MyException" << std::endl; } |
<実行結果>
MyException 続行するには何かキーを押してください・・・
例外用に「MyException」クラスを作りました。
メンバはShowMessage関数だけです。
「try」の中で、コンストラクタ関数を使ったクラスの実体を作り、そのまま「投げて」います。
※既定のコンストラクタ関数は、書かなくても自動的に作られています。
「catch」で「MyException」クラスを受け取り、メッセージを表示しています。
このように、自作のクラスを例外用に作って使う事も結構あります。
よくあるパターンが、この例外クラスを継承して使う方法です。
少しだけ複雑になりますが、上のプログラムを発展させます。
<sample program cpp082-02>
#include <iostream> class MyException { public: virtual void ShowMessage(); }; class MyDerivedException : public MyException { public: void ShowMessage(); }; int main() { try { throw MyDerivedException(); } catch (MyDerivedException myException) { myException.ShowMessage(); } catch (MyException myException) { myException.ShowMessage(); } return 0; } void MyException::ShowMessage() { std::cout << "MyException" << std::endl; } void MyDerivedException::ShowMessage() { std::cout << "MyDerivedException" << std::endl; } |
<実行結果>
MyDerivedException 続行するには何かキーを押してください・・・
「MyException」クラスを継承した「MyDerivedException」クラスを作りました。
「throw」は継承した「MyDerivedException」クラスを「投げて」います。
「MyDerivedException」クラスを「捕まえる」catchも増やしました。
増やした場所に注意してください。
「MyException」クラスを「捕まえる」前に「MyDerivedException」クラスを「捕まえる」catchを書いています。
実行結果は「派生クラス」のShowMessage関数が呼ばれているのが分かります。
「throw」で「投げる」クラスを変えてみましょう。
<sample program cpp082-03>
#include <iostream>
class MyException {
public:
virtual void ShowMessage();
};
class MyDerivedException : public MyException {
public:
void ShowMessage();
};
int main()
{
try {
throw MyException();
}
catch (MyDerivedException myException) {
myException.ShowMessage();
}
catch (MyException myException) {
myException.ShowMessage();
}
return 0;
}
void MyException::ShowMessage()
{
std::cout << "MyException" << std::endl;
}
void MyDerivedException::ShowMessage()
{
std::cout << "MyDerivedException" << std::endl;
}
|
<実行結果>
MyException 続行するには何かキーを押してください・・・
「基底クラス」の「MyException」クラスを「投げる」と実行結果が変わりました。
何が言いたいのかと言うと、
似たような「例外」を細かく分ける場合に継承が役立つ
と言う事です。
実際に他の言語では、このような仕組みが用意されています。
ファイル関係の例外を例にすると、全般的なファイルエラーで「基底クラス」を作ります。
そこから「オープンエラー」「入出力エラー」などに分けて「派生クラス」を作るのです。
皆さんも「例外クラス」上手く活用出来るように、色々と調べて試してみてください。
何度か書きましたが、詳細な説明や高度な説明は他のサイトにあふれています。
とりあえず、最低限の事だけ知っておいていただき深く知りたい方への「きっかけ」になってもらえれば幸いです。