53

例外をキャッチする方法は3つあることがわかりましたが、違いは何ですか?

1)値でキャッチします。

2)参照によるキャッチ。

3)ポインタでキャッチします。

値によるキャッチはオブジェクトの2つのコピーを呼び出し、参照によるキャッチは1つを呼び出すことだけを知っています。では、ポインタによるキャッチはどうですか?ポインタによるキャッチをいつ使用するのですか?オブジェクトをスローすることに加えて、このようなオブジェクトへのポインターをスローできますか?

class A {}

void f() {

  A *p = new A();
        throw p;


}
4

5 に答える 5

88

推奨される方法は、値でスローし、参照でキャッチすることです

あなたのコード例はポインターをスローしますが、キャッチ サイトでメモリを管理する必要があるため、これは悪い考えです。

本当にポインターをスローする必要がある場合は、 などのスマート ポインターを使用してshared_ptrください。

いずれにせよ、Herb Sutter と Alexei Alexandrescu は、私が言い換えた C++ Coding Standards の本でそれを非常によく説明しています。

C++ コーディング標準: 値によるスロー、参照によるキャッチを参照してください。

于 2010-01-07T19:30:37.000 に答える
17

Catch は、通常の代入互換性ルールに従います。つまり、値をスローした場合、それを値または参照としてキャッチできますが、ポインターとしてキャッチすることはできません。ポインターをスローすると、ポインター (またはポインターへの参照...) としてのみキャッチできます。

しかし、ポインタをスローするのは本当に意味がありません。メモリ管理の問題が発生するだけです。したがって、一般に、Gregory が説明しているように、値でスロー、参照でキャッチのルールに従う必要があります。

于 2010-01-07T19:41:16.537 に答える
5

Microsoft の MFC はポインターによるキャッチを使用しますが、try と catch が適切に実装される前は、コンパイラとの互換性のためだったと思います。もともと、彼らはそれをシミュレートするために TRY および CATCH マクロを使用していました。各例外は、オブジェクトを削除する必要があるかどうかを判断するメソッドを持つ CException から派生します。

現代の例外設計にはお勧めしません。参照によるキャッチは、行く方法です。

于 2010-01-07T19:43:43.977 に答える
3

本質的に任意のタイプの任意のオブジェクトをスローすることは可能ですが、これを行うことによって得られるものは (あるとしても) ほとんどありません。動的割り当ては、主に、オブジェクトの有効期間が自動割り当てに適合しない場合に役立ちます。つまり、その有効期間を通常のプログラム スコープから独立させたい場合です。

ただし、例外オブジェクトの場合はあまり意味がありません。例外オブジェクトは通常、例外ハンドラーの内部でのみ使用され、その例外の (最後の) ハンドラーを終了するときに、明らかに破棄する必要があります。

一般に、例外処理コードをかなり単純に保ちたいという事実もあります。たとえば、空きストア/ヒープが枯渇または破損していることを報告しようとしている場合、その枯渇/破損した空きストア/ヒープから例外オブジェクトを割り当てようとしても、通常はうまく機能しません...

于 2010-01-07T19:50:41.887 に答える
1

ポインターによって例外をキャッチ/スローするための適切なシナリオは実際にはありません。C++ のセマンティクスでは許可されていますが、ほとんどの場合、一時的な例外または文字列オブジェクトをスローするため、あまり役に立ちません。

ただし、一部のライブラリ (Boost.Graph はこれを行っていると思います) は、throw を使用して、深く再帰された関数から呼び出し元に戻り値を渡します。このような状況では、戻り値はポインターである可能性があるため、ポインターをスローすることは理にかなっています。

于 2010-01-07T19:36:24.923 に答える