闽公网安备 35020302035485号
目前的异常处理机制是,一旦异常被抛出(throw)之后,原来的执行流程就会跳转到异常捕获(catch)代码块中,两者可能经历了多次堆栈展开。那么捕获异常后能不能恢复到抛出异常的点并继续执行?这个问题在 C++ 之父 Bjarne Stroustrup 设计异常处理机制之初就被考虑和详细讨论过了。
捕捉异常后,如果想继续执行抛出异常后面紧接着的代码,需要清晰知道抛出点的上下文信息,否则就无法保证继续执行的正确性。然而,抛出点的上下文信息对于 catch 语句块来说是很难获取的,这就带来了恢复执行的不确定性。
因此,C++ 设计之初就否定了在异常处理机制中加入恢复执行的可能性。在实际的编程实践中,如果程序设计人员不希望程序业务流程被突然打断,可以在抛出异常之前先检查并尝试解决问题,只有在确实无法解决问题的情况下才抛出异常。
bool checkAndFixProblem() {
// try to fix problem
// return true;
// fix problem fail
return false;
}
void mightGoWrong() {
if (!checkAndFixProblem()) {
throw std::runtime_error("Something went wrong and couldn't be fixed");
}
}
int main() {
try {
mightGoWrong();
std::cout << "This line will not be executed if exception is thrown"
<< std::endl;
} catch (const std::runtime_error& e) {
std::cerr << "Caught an exception: "
<< e.what() << std::endl;
}
std::cout << "Program continues after catching the exception"
<< std::endl;
return 0;
}
在上面的代码中,当调用函数 mightGoWrong() 时,如果将要抛出异常,先利用函数 checkAndFixProblem() 尝试修复问题,只有在修复失败的情况下才会抛出异常。如果修复成功,程序将继续原有的流程。This line will not be executed if exception is thrown Program continues after catching the exception假设修复失败,那么程序输出:
Caught an exception: Something went wrong and couldn't be fixed Program continues after catching the exception
这种方式的代码更易于理解和维护,避免了异常处理中不必要的复杂性和不确定性。