8

例外オブジェクトがどのように作成されるのか知りたいですか?また、ハンドラー関数パラメーターが非定数参照になる可能性があるのはなぜですか?

例えば:

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")

なぜこれが可能なのか説明してもらえますか?

4

1 に答える 1

11

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

これを行う場合:

throw E("Out of memory");

(タイプ E の) オブジェクトをローカルに作成します。スローのプロセスは、このオブジェクトを標準で定義されていないプライベート メモリ ロケーションにコピーします。したがって、スローされるオブジェクトはコピー可能でなければなりません。

注: コンパイラは、コピーを最適化し、プライベートな場所に直接作成することができます。したがって、コピーされないという事実は、コンパイラがコピーを最適化して削除したためです (そのため、ローカルではなくなりました)。コピー コンストラクターをプライベートにしてみると、コンパイルに失敗します。

また、ハンドラー関数のパラメーターが非 const 参照になる可能性があるのはなぜですか?

オブジェクトをキャッチすると:

catch(E& e)

コピー先のプライベートな場所にあるオブジェクトへの参照を取得しています。const(または一時)値ではないため、通常の参照を行うことができます。

于 2012-10-21T16:18:34.590 に答える