第48章 えっ!? 4

 今回は例外を投げる場所を変えてみたいと思います。どこからでも投げていたようですが、「ここ」から投げるとどうなるのでしょうか?


 では、今回の要点です。


 では、いってみましょう。


 今まで例外を投げてきたのは、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 文に値を渡していません。こうすると、今処理している例外と同じ例外を投げます。簡単ですね。


 例外処理に入ってから、何か異様に一章が短い気がします。次はもうちょっと長めにしてみましょうか。

 それはともかく、今回の要点です。


 それでは、次回まで。


第47章 えっ!? 3 | 第49章 えっ!? 5

Last update was done on 2001.3.3

この講座の著作権はロベールが保有しています