★例外クラスを作る★


例外を扱う際に単純な型ではなく、例外用のクラスを作る場合があります。

簡単な例を書きますので、作ってみましょう。

<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」クラスを「投げる」と実行結果が変わりました。

何が言いたいのかと言うと、

似たような「例外」を細かく分ける場合に継承が役立つ

と言う事です。


実際に他の言語では、このような仕組みが用意されています。

ファイル関係の例外を例にすると、全般的なファイルエラーで「基底クラス」を作ります。

そこから「オープンエラー」「入出力エラー」などに分けて「派生クラス」を作るのです。

皆さんも「例外クラス」上手く活用出来るように、色々と調べて試してみてください。

何度か書きましたが、詳細な説明や高度な説明は他のサイトにあふれています。

とりあえず、最低限の事だけ知っておいていただき深く知りたい方への「きっかけ」になってもらえれば幸いです。


次へ

戻る

目次へ