异常捕获机制,C++

Edu*_*yan 5 c++ exception c++11

考虑以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我抛出一个类型的异常std::range_error并试图抓住它.
逻辑上catch,由于类型不匹配(std::bad_allocstd::range_error),第一个块无法捕获它.
第二个捕获块必须捕获它,因为它们是相同类型的std::range_error.
而且,当我在第二个catch块中重新抛出异常时,它必须在第三个catch块中被捕获.

所以我的输出必须是

BBB
CCC
DDD
Run Code Online (Sandbox Code Playgroud)

但我只得到BBB终止输出.

任何人都可以解释一下我的行为吗?

Whi*_*TiM 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;
}
Run Code Online (Sandbox Code Playgroud)

一个异常处理块.因此,在满足throw任何catch块中的第一个时,它会使整个块在当前范围之外寻找另一个处理块(try-catch).如果没有找到,程序将终止.

请参阅try-catchC++中的块

像你最初想的那样打印...... 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;
}
Run Code Online (Sandbox Code Playgroud)

打印:

BBB
CCC
DDD
Run Code Online (Sandbox Code Playgroud)

为了记录:请避免使用if-else生产代码中使用简单梯形图的控制流程的例外


rob*_*r78 5

要重新捕获range_error,需要新的外部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;
}
Run Code Online (Sandbox Code Playgroud)

产量

BBB
CCC
DDD
Run Code Online (Sandbox Code Playgroud)