2012-03-16 8 views
0

dynamic_cast<SomeType&>が失敗した場合bad_cast例外がスローされます。私のコードでは例外の別の階層があり、bad_castはその階層にないので、私のコードはbad_castを処理しません。代わりに別の例外をスローすることができますか?bad_castがスローされた場合にカスタムハンドラをインストールできますか?

私は、このようなカスタムハンドラ書きたいと思い意味:

void OnBadCast() 
{ 
    throw MyException("Bad cast"); 
} 

をして何とかこのハンドラが呼び出される代わりのbad_castがスローされているように、C++ランタイム

RegisterMyBadCastHandler(&OnBadCast); 

に登録。

これは可能ですか?

+0

ダイナミックキャストをラップする独自のダイナミックキャストを作成し、例外を変換します。 – Dani

+1

キャッチしないでください。 try-and-castする場合は、 'dynamic_cast'のポインタ形式を使用し、キャストの後にnullをテストします。次に、タイプが予想される場合には参照フォームを使用し、 'std :: bad_cast'はプログラムにバグがあることを示す場合に使用します。この場合、あなたはそれをバブルアップして*プログラムを止めたいと思っています*。 –

+0

@Alexandre C .:すぐにプログラムを停止することは、必ずしもオプションではありません。場合によっては、例外を記録して次の項目に進む方がよい場合もあります。 – sharptooth

答えて

1

この動作を変更することはできません。

あなたは は何ができるか

、しかし、あなた自身のキャスターを使用している:

template<class T, class E> T myCast(E expr) 
{ 
    try 
    { 
     return dynamic_cast<T>(expr); 
    } 
    catch(std::bad_cast e) 
    { 
     // custom handler 
    } 
}; 
0

あなたがそれらを処理するために、同じ階層内の例外を持っている必要はありません。少なくともVC++ではありません。さまざまなタイプのエラーを処理することだけが心配な場合は、以下のようにしてください。この回答では不十分な場合は、作業中の制限を考慮すると他のものが優れていますが、bad_castがスローされたときとスローされていないときは注意してください。 http://answers.yahoo.com/question/index?qid=20071106101012AAggZAk

#include <iostream> 
#include <exception> 

using namespace std; 

class my_exception { 
public: 
    explicit my_exception() {}; 
    const char* msg() const { return "my_exception"; } 
}; 

int main() 
{ 

    try { 

     // comment either line. 
     throw std::exception("std::exception"); 
     throw my_exception(); 

    } 
    catch (const std::exception& e) 
    { 
     cout << e.what() << endl; 
    } 
    catch (const my_exception& e) 
    { 
     cout << e.msg() << endl; 
    } 

    return 0; 
} 
1

悪いキャストは、通常、(範囲外、またはメモリ不足。例えばのような)プログラムのバグを示し、したがって、(またはおそらくトップレベルで)すべてでキャッチすべきではありません。あなたがdynamic_castの成功を分岐する場合は、ポインタの形でヌルためのテスト:あなたは特別なハンドラをしたい場合は

if (T* p = dynamic_cast<T*>(some_ptr)) 
{ 
    // Do something with p 
} 

、あなたができる最善のは、このように次のようである:

template <typename T, typename U> 
T& polymorphic_cast(U& x) 
{ 
    if (T* p = dynamic_cast<T*>(&x)) return *p; 

    my_handler(); 
} 

ここで、my_handlerはプログラムを強制終了します(おそらくエラーを記録します)。しかしここでは、プレーンなdynamic_cast<T&>フォームを好むかもしれません。std::bad_castをバブルアップし、トップレベルでログに記録してください。これは、キャストが失敗した時点で停止するように設定することもできるデバッガではより効果的です。

ケースあなたのコメントで説明のように例えば、特別な配慮を保証するのに十分な稀である:

if (auto p = dynamic_cast<foo*>(q)) { do_something(); } 
else { throw bail_me_out_of_here(); } 

、それは別の方法を試す必要があることを、いくつかの上流の戦略を示すために使用することができます。

関連する問題