2012-10-21 6 views
8

例外オブジェクトの作成方法を知りたいですか?なぜハンドラ関数のパラメータが非const参照である可能性がありますか?例えば例外オブジェクトの存続期間

class E{ 
    public: 
    const char * error; 
    E(const char* arg):error(arg){ 
    cout << "Constructor of E(): ";} 

    E(const E& m){ 
     cout << "Copy constructor E(E& m): " ; 
     error=m.error; 
    } 
}; 



int main(){ 
try{ 
    throw E("Out of memory"); 

} 
catch(E& e){cout << e.error;} 

} 

出力:Eの コンストラクタ():メモリ

のうち私はthrow E("out of memory")を持っているとE("out of memory")は単なる一時的なオブジェクトであり、何のオブジェクトがありませんコピーコンストラクタが呼び出されていないため、E("out of memory")を除き作成されました。このE("out of memory")は一時的なオブジェクトに過ぎませんが、非const参照をとるハンドラがあります。

なぜこれが可能か説明できますか?

+1

'コピーコンストラクタが呼び出されていないためです。このE( "メモリ不足")は一時的なオブジェクトにすぎませんが、非const参照を取るハンドラがあります。 - http://en.wikipedia.org/wiki/Copy_elision –

+0

@skwllsp:soこれは、一時オブジェクトが作成されず、その引数が例外オブジェクトに直接渡されたことを意味します。 – AlexDan

答えて

10

例外オブジェクトの作成方法を知りたいですか?

あなたはこれを行うと:

あなたはローカル(タイプEの)オブジェクトを作成
throw E("Out of memory"); 

。スロー処理は、このオブジェクトを標準で定義されていないプライベートメモリの場所にコピーします。したがって、スローされるオブジェクトはコピー可能でなければならない。

注:コンパイラは、コピーを最適化し、プライベートロケーションで直接作成することができます。したがって、コピーされないという事実は、コンパイラーがコピーを最適化したためです(それはもはやローカルではありません)。コピーコンストラクタをprivateにして、コンパイルに失敗するようにしてください。

なぜハンドラ関数のパラメータは非const参照になりますか?

catch(E& e) 

あなたはそれがコピーされたプライベートな場所でオブジェクトへの参照を取得している:あなたがオブジェクトをキャッチ

。 const(またはtemporary)値ではなく、通常の参照を持つことができます。

+0

そのキャッチリファレンスはどれくらい時間がかかりますか? – xaxxon

+0

@ xaxxon:http://stackoverflow.com/a/1654187/14065 –

関連する問題