2011-07-23 1 views
25

throw new FoobarException(Baz argument);またはthrow FoobarException(Baz argument);を使用するのが適切ですか?C++:例外をスローし、 'new'を使うかしないか?

キャッチするときは常にcatch(FoobarException& e)を「ちょうどいいです」と使いますが、C++(Javaは間違いなく)で新しいものを使用しなければならないのか、それともプログラマーの好みだったのかは決して確かではありません。

+2

ポインタでスローして参照でキャッチしようとすると、私はそれを捕まえるとは思わないでしょうか? –

+2

newを使うと、 'catch(FoobarException&)'はあなたのオブジェクトを捕まえません。新しいポインタを作成します。 –

答えて

33

C++での例外は、値によってスローされ、参照によって捕捉されます。

だから、これは適切な方法である:

try 
{ 
    throw FoobarException(argument); 
} 
catch(const FoobarException &ex) 
{ 
    cout << ex.what() << endl; 
} 

それが明確に定義されていない削除する責任が誰以来、新しいで作成した例外をスローしないでください。さらに、エラー処理中に割り当てを実行すると、別の例外がスローされ、元の問題が隠されます。

あなたはconstリファレンス(非constはうまく動作します)をキャッチする必要はありませんが、とにかくやってみたいです。しかし、多型的に例外をキャッチするには、常に(値ではなく)参照で行うべきです。そうしないと、例外の型をスライスすることができます。

+0

例外は常に値ではなく参照によって常にキャッチされるべきですか?派生したオブジェクトを値で渡して、メソッドが基本クラスのオブジェクトの引数を期待しているために、オブジェクトのスライスの問題について言いましたか? – Destructor

7

特別な要件がない限り、私はいつも価値あるものを投げ、constの参照によってキャッチします。これは、new自体も例外をスローする可能性があるため、エラー処理中に例外を引き起こす可能性のあるものを避けることが最善です。

+0

そうです、別の例外がアクティブである間に例外をスローすることは本質的に禁止されています(私はそれがUBだと思うので)、標準の 'new'が出ています。 –

+1

My 2c's:@KerrekSBのsageアドバイスに追加するだけで、実際に定義された動作です(http://en.cppreferenceを参照してください)。 .com/w/cpp /エラー/終了)。前述のリンクは、デストラクタから例外をスローするなど、他の多くのことを避けることも指しています。スタックが以前にスローされた例外に対して解放されている間に例外を発生させる可能性があるからです。 – Rob

関連する問題