2010-11-25 35 views
4

なぜstd::exception::whatメンバー機能がconstなのか不思議ですか?なぜC++のstd :: exception :: whatメンバーはconstですか?

class exception 
{ 
public: 
    exception() throw() { } 
    virtual ~exception() throw(); 

    /** Returns a C-style character string describing the general cause 
    * of the current error. */ 
    virtual const char* what() const throw(); 
}; 
+4

なぜ非constにする必要がありますか? –

答えて

16

what()メンバ関数を呼び出すと、exceptionオブジェクトの観察可能な状態を変更するべきではありません。

通常、例外はconst参照によって捕捉されます。 what()メンバ関数はconst修飾しなかった場合は、catchブロック内から呼び出すことができなくなるため、例えば、

try { 
    // ... 
} 
catch (const std::exception& ex) { 
    std::cout << ex.what(); 
} 

、このパターンは動作しないでしょう。

what()から返される文字列を生成する必要がない場合は、その文字列を可変メンバ変数にマテリアライズすることができます。

+1

あなたは私の次の質問を認識しています。 –

+0

実際に私が例外を見たコードのほとんどは、あなたがそれらを変更するために何もできないにも関わらず、参照によって捕らえられます。古い習慣だと思います。 –

4

Exceptionインスタンスを変更しないためです。

一般に、クラスインスタンスを変更しないすべての関数はconstと宣言する必要があり、const修飾変数で呼び出すことができます。

2

推論はおそらく安定性を維持したいという要望から来ています。たとえば、プロセスのメモリが不足した場合、例外がスローされる可能性があります。そうであれば、 "What"を変更してより多くのスペースを必要とすることに反する生産性があります。プログラマがそのような状況下でそれを試みた場合、それは直ちにプログラム全体を中止します。おそらくあなたが意図したものではありません。

同様に、スタックから余分なスペースを使用するのは適切ではありません。スローされた例外の間は、まさにuwindingなのですから。

昇圧ライブラリにはboost :: exceptという例外があります。になりますので、例外が上向きになると材料を追加できます。買い手責任負担。

+0

これは興味深い追加であり、ポインタが返され、文字列が返されない理由を半回答します。 –

3

質問を反転します。なぜそれはconstではないでしょうか?

"char * what()const"の場合、what()がポインタを返す内部char配列を変更できます。そのような方法で任意のコードが内部バッファを操作できるようにするためにはexception()が驚くほど愚かなので、what()はchar *の代わりにconst char *を返します。

const修飾子なしで "const char * what()"だった場合、what()を呼び出すと例外の内部状態が変更されることになります。それは、あなたがそれがすることを期待していないとしない。

私たちは "const char * what()const"を持っています。 const配列へのポインタを返すconst関数。結果はconst参照で呼び出すことができます。どの例外が一般的であるか。

通常、例外を変更することはなく、例外をスローしてスローし、処理コードで変更せずに例外を操作することができます。したがって、メンバー関数はconstでなければなりません。

関連する問題