2016-09-11 19 views
5

は、このコードを考えてみましょう:ここ例外、C++

int main() 
{ 
    try 
    { 
     throw std::range_error(""); 
    } 
    catch (std::bad_alloc) 
    { 
     std::cout << "AAAA" << std::endl; 
     throw; 
    } 
    catch (std::range_error) 
    { 
     std::cout << "BBB" << std::endl; 
     throw; 
    } 
    catch (std::exception) 
    { 
     std::cout << "CCC" << std::endl; 
    } 
    std::cout << "DDD" << std::endl; 
} 

私はタイプstd::range_errorの例外をスローし、それをキャッチしようとしています。
論理的に最初のcatchブロックは、タイプの不一致(std::bad_allocおよびstd::range_error)のためにキャッチできません。
2番目のcatchブロックは、同じタイプのstd::range_errorであるため、キャッチする必要があります。
また、2番目のcatchブロックで例外を再現するときは、3番目のcatchブロックでcatchする必要があります。

だから私の出力は

BBB 
CCC 
DDD 

でなければなりません。しかし、私は唯一の終了にBBB出力を取得します。

誰でも私にその行動を説明していただけますか?

+2

出力はあなたの第二スロー 'try'ブロックでは発生しませんでした。だからそれは捕まえられない。 – Galik

+2

それはそのようには動作しません。それぞれのtry-catchブロックは、いくつのcatch節があっても、例外で1つのショットしか取得しません。 catch節によってスローされた例外は、そのtry-catchブロックで捕捉されません。 – davidbak

+0

これは、例外タイプのブロックを多数取得しても、最初のものだけが例外をキャッチすることを意味します。 –

答えて

6

あなたがthrow例外を再とき、あなたは現在の例外処理ブロックの文脈から完全に投げている....だから、

try 
{ 
    throw std::range_error(""); 
} 
catch (std::bad_alloc) 
{ 
    std::cout << "AAAA" << std::endl; 
    throw; 
} 
catch (std::range_error) 
{ 
    std::cout << "BBB" << std::endl; 
    throw; 
} 
catch (std::exception) 
{ 
    std::cout << "CCC" << std::endl; 
} 

1つの例外処理ブロックです。したがって、catchブロックのいずれかにある最初のthrowを満たすと、ブロック全体が、現在の有効範囲外の別の処理ブロック(try-catch)を探すようになります。見つからなければ、プログラムは終了する。

... Live On Coliru ...あなたが最初に思ったように印刷するには

int main() 
{ 
    try{ 
     try{ 
      try{ 
       throw std::range_error(""); 
      } 
      catch (std::bad_alloc) { 
       std::cout << "AAAA" << std::endl; 
       throw; 
      } 
     } 
     catch (std::range_error) { 
      std::cout << "BBB" << std::endl; 
      throw; 
     } 
    } 
    catch (std::exception){ 
     std::cout << "CCC" << std::endl; 
    } 
    std::cout << "DDD" << std::endl; 
} 

プリントtry-catch block in C++

を参照してください。レコードの

BBB 
CCC 
DDD 

:制御のための例外を使用して避けてくださいを生産コード内の単純なif-elseはしごで行うことができるフロー

この
4

catch (std::range_error) 
{ 
    std::cout << "BBB" << std::endl; 
    throw; // <== this one 
} 

tryの本体内で、それ自体ではないので、それが見つかるまで、例外処理メカニズムは、一度に1つのスコープを外出続けるとき。他の外側にはtryが存在しないため、例外はまったくキャッチされません。

例外処理には再入荷がありません。

5

range_errorとnew outer try catchブロックを再捕捉する必要があります。

#include <iostream> 

int main() 
{ 
    //outer try catch ------------------------ 
    try { 

    // inner try catch --------------------- 
    try 
    { 
     throw std::range_error(""); 
    } 
    catch (std::bad_alloc) 
    { 
     std::cout << "AAAA" << std::endl; 
     throw; 
    } 
    catch (std::range_error) 
    { 
     std::cout << "BBB" << std::endl; 
     throw; 
    } 
    // ------------------------------- 
    } 

    catch (std::exception) 
    { 
    std::cout << "CCC" << std::endl; 
    } 
    // -------------------------------- 

    std::cout << "DDD" << std::endl; 
} 

BBB 
CCC 
DDD