根据我的理解,此代码无法正常工作
是的,对于您描述的场景,它可以正常工作。
在外部 try 块中抛出的异常将首先命中内部 catch 语句,因为这是代码中第一个可到达的 catch 语句。
这是不正确的。这与代码中的顺序无关,而与范围中的顺序有关。如果外部try 抛出,则内部try 不在范围内。异常向上调用堆栈,从当前范围开始,然后是最近的外部范围,然后是下一个外部范围,依此类推,直到找到匹配的catch。例如:
try {
// if any std exception is thrown here, jumps to A below...
try {
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
for (int i = 0; i < n_files; ++i)
{
try {
// if any std exception is thrown here, jumps to C below...
}
catch (std::exception& e) // C
{
// print error
continue;
}
}
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
}
catch (invalid_argument& e) // B
{
// print error
return 0;
}
}
catch (exception& e) // A
{
// print error
return 0;
}
像这样的嵌套 try-catch 会是错误的形式/从我所读的内容中读取会令人困惑。
这也不对。使用嵌套的try 块没有任何问题。
然而,在这个例子中,让内部 try 捕获 ONLY std::invalid_argument 和 std::runtime_error 会更有意义,因为它们是它期望和愿意的两种类型忽略以继续循环。不要在那个地方抓到std::exception。这样,如果process_file() 抛出了一些意外(例如std::bad_alloc),那么外部catch 应该处理它以终止进程。
try {
// if any std exception is thrown here, jumps to A below...
try {
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
for (int i = 0; i < n_files; ++i)
{
try {
// if std::invalid_argument is thrown here, jumps to D below...
// if std::runtime_error is thrown here, jumps to C below...
// if any other std exception is thrown here, jumps to A below...
}
catch (std::invalid_argument& e) // D
{
// print error
continue;
}
catch (std::runtime_error& e) // C
{
// print error
continue;
}
}
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
}
catch (invalid_argument& e) // B
{
// print error
return 0;
}
}
catch (exception& e) // A
{
// print error
return 0;
}
设计catch 的最佳方法是让它只捕获它知道如何在代码中的那个位置处理的特定 类型的异常。让外部catch 处理其他所有事情。如果抛出异常并且没有找到匹配的catch来处理它,则进程将默认终止。