5

現在、Visual Studio Express C ++ 2008を使用していますが、キャッチブロックの順序についていくつか質問があります。残念ながら、インターネットで答えが見つからなかったので、専門家にこれらの質問を投げかけています。

catch(...)がcatchブロックの最後に配置されていない限り、コンパイルはエラーC2311で失敗することに気付きました。たとえば、次のようにコンパイルされます。

catch (MyException)
{
}
catch (...)
{
}

次はしませんが:

catch (...)
{
}
catch (MyException)
{
}

a。これがC++言語標準で定義されているのか、それともMicrosoftコンパイラが厳密であるだけなのかを尋ねることはできますか?

b。C#とJavaにも同じルールがありますか?

c。余談ですが、基本クラスと派生クラスを作成し、派生クラスのcatchステートメントの前に基本クラスのcatchステートメントを配置することも試みました。これは問題なくコンパイルされました。そのような慣習を防ぐ言語基準はありませんか?

4

3 に答える 3

5

規格によると、順序は重要です。基本的に、例外に一致する最初のキャッチがキャッチされます。

a)catch(...)後続のキャッチは無関係になるため、標準では最後のキャッチのみが許可されます。

b)C#とJavaには同様のルールがあります。

c)派生クラスが派生クラスのコードを無関係にする前に、ベースを(参照またはポインターで)キャッチします。ただし、標準ではこれが許可されています

于 2010-03-08T22:04:42.003 に答える
3

C ++ Standard 15.3 / 5「例外の処理」から:

tryブロックのハンドラーは、出現順に試行されます。これにより、たとえば、対応する基本クラスのハンドラーの後に派生クラスのハンドラーを配置するなど、実行できないハンドラーを作成できます。

ハンドラーの例外宣言のAは、関数パラメーター宣言の...場合と同様に機能します。...例外の一致を指定します。存在する場合、...ハンドラーはそのtryブロックの最後のハンドラーになります。

于 2010-03-08T22:04:39.540 に答える
3

いわゆるデフォルトハンドラーcatch(...)は、ハンドラーのリストの最後のハンドラーである必要があります。これは確かに規格で要求されています。ただし、この要件はデフォルトハンドラーに固有です。

それ以外の場合、標準はハンドラーの順序を制限しません。つまり、通常、リストの下にある他のハンドラーに到達するすべての例外を「インターセプト」するハンドラーを作成できます(したがって、後者のハンドラーは役に立たなくなります)。

さらに、同じcatch句を(同じタイプで)数回繰り返すことは完全に合法です

catch (int) {
  // ...
}
catch (int) {
  // ...
}

最初のものだけが何かを捕まえるチャンスがあるとしても。優れたコンパイラは、そのような場合に警告を発行しますが、正式にはエラーではありません。

于 2010-03-08T22:06:35.380 に答える