2017-02-27 1 views
0

std::runtime_errorを投げて未処理にすると、端末は自動的にwhat()の結果を表示し、デバッグを非常に簡単にします。例:未処理のカスタム例外をスローした後にwhat()を呼び出すにはどうすればよいですか?

#include <iostream> 

int main() 
{ 
    throw std::runtime_error("This is an error message.\n"); 
} 

コンソール出力:このクラスによって派生

​​

カスタム例外クラスが同じ挙動を示し、ゼロから作られた例外クラスは、デフォルトではそれを行うませません。

私が作成したい例外クラスは、std::runtime_errorから派生するものであってはなりません。また、デバッグの目的で、プログラムがクラッシュした後でもwhat()を印刷する必要があります。誰かが私を助けることができますか?現時点で

が、それは次のようになります。

#include <iostream> 

struct Custom_Exception 
{ 
    std::string Msg; 

    Custom_Exception(std::string Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    std::string what() noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    throw Custom_Exception("This is an error message.\n"); 
} 

コンソール出力:

terminate called after throwing an instance of 'Custom_Exception' 

エラーメッセージではありませんwhat(): ...デストラクタにstd::cout<<Msg;を置くことはどちらか助けていません。

ご意見をお寄せください。ありがとうございました。 std::terminate_handlerwhat()を使用する

+4

"ただし、作成したい例外クラスは、std :: runtime_errorから派生してはいけません。" - 何故なの? –

+2

メインであなたの例外をキャッチし、それらであなたが望むことをしてください。私はあなたのためにこれを実行するためにランタイムに依存しません。 –

+0

@NeilButterworth私は特定のデータ型を使用するか、毎回変換する必要があります。自分のプロジェクトに使用する汎用例外クラスを作成できないため、この機能を追加する方法を知りたい好奇心。私はちょうどそのようには好きではありません。さもなければ、私はstd :: runtime_errorそれ自体を使うことができます...しかし、それは特定のものstd :: runtime_errorができないので、カスタム例外クラスによって欲しいです。 – Thynome

答えて

4

最小例外インターフェースはstd::exceptionです:

struct Custom_Exception : public std::exception { 
    std::string Msg; 
public: 
    Custom_Exception(std::string Error_Msg) noexcept : Msg(Error_Msg) { 
    } 

    const char* what() const { return Msg.c_str(); } 
}; 

別のオプションstd::exceptionインタフェースから継承することなく、main()

int main() 
{ 
    try { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch(const Custom_Exception& ce) { 
     std::cerr << ce.what() << std::endl; 
    } 
} 

にカスタム例外をキャッチすることですまたはオーバーライドしてstd::terminate_handlerをあなた自身のHAで設定しますndler。

+0

'std :: terminate_handler'を適切にオーバーライドする方法と、それを私の例外クラスにどのように統合できるのか説明できますか? – Thynome

+0

@Thynome最後に、 'std :: terminate_handler'オーバーライド関数が' try {throw; } catch(const Custom_Exception&ce){/ * ... * /} '。 –

+0

できます。 [except.handle]/7は、暗黙のハンドラ は、スロー*のためにstd :: terminate()[...]が入力されたときにアクティブであるとみなされるため、そこから例外を安全に再スローすることができます。 –

0

仮想デストラクタと仮想what()メソッドを提供するstd :: exceptionから例外を引き出す必要があります。デストラクタをオーバーライドすると、メッセージを印刷できるはずです。

#include <iostream> 
#include <exception> 

class Custom_Exception : std::exception 
{ 
    char const* Msg; 

    Custom_Exception(char const* Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    Custom_Exception(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
    } 

    Custom_Exception& operator=(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
     return *this; 
    } 

    virtual ~Custom_Exception() 
    { 
    } 

    virtual char const* what() const noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    try 
    { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch (Custom_Exception& ex) 
    { 
     std::cout << "what(): " << ex.what(); 
    } 
} 
+0

例外がスローされない場合でも、このエラーメッセージは出力されませんか?そして、それが捕まっても? –

+0

ああ、そうです。例外が破棄されるたびに。 πάνταῥεῖの外側のキャッチに対する答えはうまくいくかもしれません。 –

+0

エラーメッセージを出力するのはデストラクタの責任ではありません。それが必要なときにエラーメッセージを返すために 'what()'が存在する理由です。 –

関連する問題