35

私のコードに次のスニペットがある場合:

try {
  doSomething();
} catch (...) {
  doSomethingElse();
  throw;
}

デフォルトの省略記号ハンドラーによってキャッチされた特定の例外をスローが再スローしますか?

4

1 に答える 1

43

はい。例外は、キャッチされるまでアクティブであり、そこで非アクティブになります。ただし、ハンドラのスコープが終了するまで存続します。標準の強調鉱山から:

§15.1/4: スローされる例外の一時コピー用のメモリは、3.7.4.1 に記載されている場合を除き、不特定の方法で割り当てられます。その例外に対して実行されているハンドラーがある限り、一時的なものは持続します。

あれは:

catch(...)
{ // <--

    /* ... */

} // <--

これらの矢印の間で、例外を再スローできます。ハンドラーのスコープが終了したときにのみ、例外は存在しなくなります。

実際、§15.1/6 で指定された例は、コードとほぼ同じです。

try {
    // ...
}
catch (...) { // catch all exceptions
    // respond (partially) to exception <-- ! :D
    throw; //pass the exception to some
           // other handler
}

throwアクティブな例外がない場合terminateは、呼び出されることに注意してください。これは、ハンドラーにいるあなたには当てはまりません。


スローされ、例外に対応するハンドラーがない場合doSomethingElse()、元の例外は処理済みと見なされるため、新しい例外がそれを置き換えます。(投げたばかりのように、スタックの巻き戻しを開始するなど)

あれは:

void doSomethingElse(void)
{
    try
    {
        throw "this is fine";
    }
    catch(...)
    {
        // the previous exception dies, back to
        // using the original exception
    }

    try
    {
        // rethrow the exception that was
        // active when doSomethingElse was called
        throw; 
    }
    catch (...)
    {
        throw; // and let it go again
    }

    throw "this replaces the old exception";
    // this new one takes over, begins stack unwinding
    // leaves the catch's scope, old exception is done living,
    // and now back to normal exception stuff
}

try
{
    throw "original exception";
}
catch (...)
{
  doSomethingElse();
  throw; // this won't actually be reached,
         // the new exception has begun propagating
}

もちろん、何もスローthrow;されない場合は到達し、キャッチされた例外が期待どおりにスローされます。

于 2010-03-19T01:24:35.890 に答える