1. ホーム
  2. c++

[解決済み] throw new std::exception vs throw std::exception

2022-07-19 05:15:48

質問

あるコードを見ているときに、偶然見つけました。

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

を使う必要はない/使うべきでない、といつも思っています。 new を使う必要はないと思っていました。

正しい方法は何ですか、どちらもOKですか、もしそうなら何か違いがありますか?

ところで、私が見たところ、PowerShell のブーストライブで "grepping" をするとき、決して throw new .

追伸:また、いくつかのCLIコードで throw gcnew . これはOKですか?

どのように解決するのですか?

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

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

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

事実上、これは堅牢なコードを書くことを容易にするはずの例外処理機能を取ってしまい、すべての状況で正しいコードを書くことを非常に困難にしてしまったことを意味します。これは、この機能を期待していないクライアントコードのために、ライブラリコードとして動作することがほとんど不可能になるという問題はさておきです。