考虑以下代码:
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
块无法捕获它。
第二个catch块必须捕获它,因为它们是std::range_error
的相同类型
而且,当我在第二个catch块中重新抛出异常时,它必须在第三个catch块中被捕获。
所以我的输出必须是
BBB
CCC
DDD
但我只得到终止的BBB
输出。
有人能解释一下我的行为吗?
答案 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;
}
是一个异常处理块。因此,在满足任何throw
块中的第一个catch
时,它会使整个块在当前范围之外寻找另一个处理块( 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;
}
打印:
BBB
CCC
DDD
为了记录:请避免在生产代码中使用简单的if-else
梯形图来控制流程的异常
答案 1 :(得分: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;
}
输出
BBB
CCC
DDD
答案 2 :(得分:4)
这throw
:
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw; // <== this one
}
本身并不在try
的主体内,所以当异常处理机制一次一个地继续运行时,直到找到一个。由于没有其他外部try
,因此根本没有发现异常。
异常处理中没有重入。