0

私はruntime_error、c'torから派生し、intを取得している独自の例外クラスを作成しました。

ポリモーフィズムを使用するために、この例外の基本クラスを作成したいので、基本クラスのみをキャッチでき、基本的には派生クラスをキャッチして、そこから.what()メソッドを呼び出します。

したがって、これは基本クラスです:(別のcppファイルのofcでbaseException ::〜baseException(){}を取得しました)

class baseException
{
    virtual ~baseException()=0 {}
    virtual const char* what()=0;
};

そしてこれは派生クラスです:

class myException: public runtime_error, public baseException
{
public:
    myException(int): runtime_error("Error occured") {}
    const char* what() {return runtime_error::what();}
};

しかし、メインで私が書くとき:

catch(baseException* x)
{
cout<<x->what();
}

myExceptionがbaseExceptionを継承していても、スキップしてブロックには入りません。何か提案はありますか?

4

4 に答える 4

2

ポインタではなく、参照(またはconst参照)で例外をキャッチする必要があります。

于 2012-06-18T13:01:13.283 に答える
2

あなたにはメソッドbaseExceptionがありません。おそらくから派生する必要があります。whatbaseExceptionruntime_error

class baseException : public runtime_error
{
public:
    baseException(const std::string& what) : runtime_error(what) {}
};

その後

class myException: public baseException
{
public:
    myException(int): baseException("Error occured") {}
};

私は次のイディオムを好みますが:

class myException: public baseException
{
public:
    myException(int x): baseException(getWhatMessage(x)) {}

private:
    static std::string getWhatMessage(int x) { /*generate the message*/ }
};

部分的にcatch。を使用して投げる場合はthrow myException(5)、このようにキャッチする必要があります

catch(baseException& x)
{
    cout<<x.what();
}
于 2012-06-18T13:04:53.420 に答える
1

baseExceptionオブジェクトへの参照をキャッチします。そのため、そのクラスのメソッドを知っているだけです。baseExceptionただし、呼び出されるメンバーはありませんwhat()。これによりエラーが発生します。直接baseException派生runtime_errorまたはキャッチしmyExceptionます。

編集:

このスニペットは、ポインタが例外と一緒に機能してはならない理由がまったくないことを示しています。

#include <iostream>
#include <string>

class A {
public:
    virtual int test() = 0;
};

class B : public A {
public:
    virtual int test() {
        return 42;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    try {
        throw new std::string("foo");
    } catch (std::string* ecx){
        std::cout << *ecx << std::endl;
    }

    try {
        throw new B();
    } catch (A* ecx) {
        std::cout << ecx->test() << std::endl;
    }
}

出力:

foo

42

于 2012-06-18T13:01:36.823 に答える
1

更新:この回答は、質問の元のバージョンに基づいていました。現在、問題は発生していないようwhat()です(基本クラスで再宣言することで問題を回避したため)。問題は、単にポインタをキャッチしようとして、(おそらく)値をスローしようとしていることです。解決策は、参照によってキャッチすることです。

catch (myException const & ex) {
    std::cerr << ex.what() << std::endl;
}

(の宣言を修正すると仮定しますwhat()const何らかの理由でそれを非にする必要がある場合は、行からconst削除します)。constcatch

what()で宣言されていない場合の呼び出し方法を説明する元の回答baseException

キャッチしたいbaseException*

あなたは捕まえたほうがいいでしょうbaseException const &; ポインタを投げる賢明な方法はありません。

.what()そしてそれらのメソッドを呼び出します

に電話したい場合は、代わりにwhat()キャッチしたほうがいいかもしれません。std::exception const &基本クラスの機能も必要な場合を除きます。その場合、おそらく基本クラスはstd::runtime_error;から継承する必要があります。または、おそらくから継承する必要がありstd::exceptionます。その場合、myExceptionタイプは仮想継承を使用する必要があります。

現状のクラスから本当にアクセスしたい場合はwhat()、以下にクロスキャストする必要がありますstd::exception

catch (myException const & ex) {
    std::cerr << dynamic_cast<std::exception const &>(ex).what() << '\n';
}
于 2012-06-18T13:10:27.973 に答える