2017-07-08 13 views
0

カスタム例外クラスを作成してスローしてエラーメッセージを表示しようとしていますが、何か間違ったことが起きて例外がスローされず、メッセージが表示されません。C++のカスタム例外メッセージが表示されない

class UnbalancedParenthesesException : public std::exception { 
    int line_number {0}; 
public: 
    UnbalancedParenthesesException(int line_number) : 
    line_number { line_number } 
    {} 

    virtual const char* what() const throw() { 
    std::string exception_message = 
     "Papentheses imbalance at line " + std::to_string(line_number) + "\n"; 

    return exception_message.c_str(); 
    } 
}; 

次のように私はtry/throw/catchにしようとしています:

はここで例外クラスです

void handle_closed_paren(int line_number) { 
    try { 
    if (definitely_unbalanced()) { 
     throw UnbalancedParenthesesException(line_number); 
    } 
    } catch (const UnbalancedParenthesesException& e) { 
     std::out << e.what() << "\n"; 
} 

コンソールでこのエラーに関連するものは何もありません。

ありがとうございます。

+2

'EXCEPTION_MESSAGEを返します。 c_str(); 'は戻り時に破棄されるローカルスタック変数のアドレスを返します。 –

+0

@リチャードクリートン:アンサーはおかげで下に行く –

+0

ありがとう、リチャード。それは確かに問題です。 – progfan

答えて

1

範囲外のstd::stringc_str()の結果を返すと、プログラムの動作が未定義です。なんでも起こる可能性がある。

それ以外では、例外が表示されない場合、おそらくdefinitely_unbalanced()の結果がfalseであるため、例外がスローされませんでした。

デバッガを使用してプログラムをステップ実行します。

+0

ありがとう、それは問題です。ローカルの 'string'ではなく、' char * 'を返さなければなりません。 – progfan

+0

@progfan:まあ、いいえ、それは修正のようには聞こえません。誰がそれを指し示すのか?誰がそれを破壊するのですか? 'std :: string'を例外オブジェクトのメンバとして(コンストラクタで構築する)保つことをお勧めします。それで安全に' c_str() 'を返すことができます。 –

+0

あなたは正しいです。このように乱雑になります。コンストラクタで 'string'を構築します。 – progfan

2

あなたwhat()方法は、ローカルstd::string変数を作成し、std::stringがスコープの外に出るとときwhat()終了を破棄されたときにダングリングを残されるその内部データへのポインタを返します。

クラスのメンバであるstd::stringにエラーメッセージを格納する必要があります。そのため、スコープの範囲外になることはありません。幸いなことに、std::exceptionには既に内部目的のためにstd::stringがあります。だから、代わりにwhat()自体にエラーメッセージをフォーマットするのは、あなたの派生コンストラクタでそれをフォーマットする必要がありますし、基本クラスのコンストラクタに渡し、ベースwhat()方法として-でそれを返すせ:

class UnbalancedParenthesesException : public std::exception 
{ 
    int mLineNumber; 
public: 
    UnbalancedParenthesesException(int line_number) : std::exception("Parentheses imbalance at line " + std::to_string(line_number)), mLineNumber(line_number) {} 

    // optional, if the catcher needs access to the value 
    int lineNumber() const { return mLineNumber; } 
}; 
+0

ありがとう、私はこの解決策が好きです。私はあなたがここでやっているように私が作ることができるか分からなかった。 – progfan

関連する問題