5

私の理解では、c++ のすべての例外は最終的に拡張されexceptionます。Java の世界でException eは、例外の種類に関係なくキャッチが機能していました。これは C++ でどのように行われますか?

このスニペットで例外がキャッチされないのはなぜですか?

try{        
    int z = 34/0;
    cout << "This line should not appear" << endl;
} catch (exception e) {
    cout << "An error has occurred: " << e.what();  // Not executed
}

また、C++ では、どのアクションがどの例外を引き起こすかをどのように調べることができますか?

4

4 に答える 4

6

このスニペットで例外がキャッチされないのはなぜですか?

で割った整数0は、標準の C++ 例外ではありません。したがって、この場合、例外はスローされず、プレーンなUndefined Behaviorが得られます。

一部の特定のコンパイラは、このシナリオを特定の例外にマップする可能性があり、コンパイラのドキュメントを確認して同じものを見つける必要があります。ただし、そのような機能を使用すると移植性がなくなり、コードは特定のコンパイラに制限されます。

このようなシナリオでできる最善の方法は、エラー状態 (除数がゼロに等しい) を自分でチェックし、明示的に例外をスローすることです。

また、C++ では、どのアクションがどの例外を引き起こすかをどのように調べることができますか?

std::exceptionクラスは、これ専用のメソッドを提供しますstd::exception::what()

于 2012-08-29T03:47:26.770 に答える
2

0 で除算すると、ほとんどの CPU は、その CPU メーカーの専門用語で例外、シグナル、割り込み、トラップなどと呼ばれる何らかのエスカレーション手順に従います。これらのどれも、「例外」という用語が使用されていても、C++ 言語の例外と直接関係はありません。

C++ では、ゼロ除算を繰り返しテストするのは一般に CPU サイクルとオブジェクト コードのサイズにコストがかかるため、組み込み型のコンパイラ生成コードはそのようなチェックを行う必要はありません。実際には、通常、プログラマーがゼロ除算を回避するようにコーディングし、除算が有用な部分のサブセットに明示的なチェックを挿入することを信頼するだけで十分です。冗長性を避けるために、そのようなチェックを因数分解します。

プログラマーが一貫性のある保証されたチェックを必要とする場合、組み込みの数値型の代わりに使用できるユーザー定義型 (カスタムのオーバーロードされた演算子を持つクラス) を作成できますが、ゼロ除算 (またはアンダーフロー、オーバーフローまたは開発者が持つその他の懸念事項) と、プログラマーが好きなように反応します。JAVA や C# などの言語には演算子のオーバーロードがないことがわかります。これは、直感的な数学演算子を使用する代わりに、関数を明示的に呼び出すために侵襲的なコード変更が必要なため、この方法で組み込み型を簡単に置き換えることができないことを意味すると思います。

とにかく、C++ 標準自体はゼロ除算の状況での動作を指定していないため、実装は、必要に応じて潜在的に有用な動作を自由に提供できます。これには、実際の C++ 言語の例外を何らかの方法で生成することが含まれる可能性がありますが、実際には、正当化するには CPU サイクルとコード サイズが高すぎる可能性があります。おそらく、JAVA は非常に遅くて肥大化しているため、このような少し余分なチェックはここにもそこにもありません...? ;-)

x86 ファミリーの CPU を使用しているとします。0 による除算通知の用語は「割り込み」です。ただし、そのマシンで UNIX や Linux などを実行している場合、分割はオペレーティング システム レベルでの「シグナル」となり、シグナル ハンドラを設定して問題の通知を受け取ることができます。

于 2012-08-29T04:32:38.813 に答える
1

あなたが書く

C ++のすべての例外が最終的に拡張されることは私の理解ですexception

それは間違っている。C++ 例外は、ほとんどすべての型にすることができます。C++98 ではコピー可能である必要がありましたが、おそらく (そして最も可能性が高い) C++11 でその制限が解除されました。

Java の世界では、例外の種類に関係なく、例外 e をキャッチすることができます。これはC++でどのように行われますか?

キャッチオール条項により、

    catch( ... )

これに関する主な問題は、例外に関する情報が必要な場合、C++98 では再スローする必要があることです。これは特に効率的な方法ではありません。また、2012 年の時点では、C++11 の例外処理機能はツールチェーンでまだサポートされていない可能性があります。

このスニペットで例外がキャッチされないのはなぜですか?

C++ の例外がないためです。通常、コンパイラは定数式のコンパイルを単に拒否します34/0。g++ を除いて、それコンパイルするコンパイラは考えられません。実際にそのコードをコンパイルしましたか? .

とにかく、そのコードをコンパイルできたとしても、標準的な C++ の観点からは、単にUndefined Behaviorが発生し、何も起こらないことになります。運が良ければ を獲得できますが、signal保証はありません。ただし、プラットフォーム固有の機能を使用して、そのようなイベントをキャッチすることは可能です。

于 2012-08-29T04:55:56.527 に答える
0

C++ では、ゼロ除算は例外を発生させません。たとえば、ここここ、およびここを参照してください。

于 2012-08-29T03:47:45.743 に答える