127

私が偶然見つけたいくつかのコードを見ている間:

throw /*-->*/new std::exception ("//...

そして私はいつもあなたがここで使う必要はない/使うべきではないと思っていnewました。
正しい方法は何ですか、どちらもOKですが、違いはありますか?

ところで、PowerShellブーストライブラリを使用して「grepping」しているときに表示される内容から、を使用することはありませんthrow new

PSまた、を使用するCLIコードをいくつか見つけましたthrow gcnew。それは大丈夫ですか?

4

5 に答える 5

98

例外をスローしてキャッチする従来の方法は、例外オブジェクトをスローし、参照 (通常はconst参照) によってキャッチすることです。C++ 言語では、コンパイラが適切なコードを生成して例外オブジェクトを構築し、適切なタイミングで適切にクリーンアップする必要があります。

動的に割り当てられたオブジェクトへのポインターをスローすることは、決して良い考えではありません。例外を使用すると、エラー状態に直面したときに、より堅牢なコードを記述できるようになるはずです。従来の方法で例外オブジェクトをスローすると、適切な型を指定する catch 句によってキャッチされたcatch (...)かどうか、または によって再スローされたかどうかにかかわらず、適切なタイミングで正しく破棄されることを確認できます。(唯一の例外は、まったくキャッチされない場合ですが、これはどのように見ても回復不可能な状況です。)

動的に割り当てられたオブジェクトへのポインターをスローする場合、例外をスローしたい時点でコール スタックがどのようなものであっても、正しいポインター型を指定し、適切なdelete呼び出しを持つ catch ブロックがあることを確認する必要があります。catch (...)そのブロックが例外を再スローしない限り、例外をキャッチしてはなりません。例外は、例外を正しく処理する別の catch ブロックによってキャッチされます。

事実上、これは、堅牢なコードの記述を容易にし、すべての状況で正しいコードの記述を非常に困難にする例外処理機能を採用したことを意味します。これは、この機能を想定していないクライアント コードのライブラリ コードとして機能することはほとんど不可能であるという問題を脇に置きます。

于 2012-06-09T20:44:23.153 に答える
34

new例外をスローするときに使用する必要はありません。

書くだけ:

throw yourexception(yourmessage);

そして次のようにキャッチします:

catch(yourexception const & e)
{
      //your code (probably logging related code)
}

直接または間接的にyourexception派生する必要があることに注意してください。std::exception

于 2012-06-08T11:53:54.430 に答える
24

呼び出しサイトがをキャッチすることを期待している場合、スローnew std::exceptionは正しいですstd::exception*。しかし、例外へのポインタをキャッチすることを誰も期待していません。あなたがあなたの関数が行うことを文書化し、人々が文書を読んだとしても、彼らはそれでも忘れて、std::exception代わりにオブジェクトへの参照を捕まえようとする傾向があります。

于 2012-06-08T11:58:52.303 に答える
9

C ++ FAQには、これに関するすばらしい議論があります。

  1. https://isocpp.org/wiki/faq/exceptions#what-to-catch
  2. https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc

基本的に、「そうしない正当な理由がない限り、参照でキャッチします。値でキャッチすることは避けてください。コピーが作成され、コピーがスローされたものとは異なる動作をする可能性があるためです。非常に特殊な状況でのみ、ポインタでキャッチする必要があります。 「」

于 2012-06-08T12:04:34.097 に答える