C++ 异常被捕捉后还能恢复执行?


以下内容为本人的烂笔头,如需要转载,请全文无改动地复制粘贴,原文链接 微信公众号「ENG八戒」mp.weixin.qq.com/s/kDMrA-28M...

目前的异常处理机制是,一旦异常被抛出(throw)之后,原来的执行流程就会跳转到异常捕获(catch)代码块中,两者可能经历了多次堆栈展开。那么捕获异常后能不能恢复到抛出异常的点并继续执行?

这个问题在 C++ 之父 Bjarne Stroustrup 设计异常处理机制之初就被考虑和详细讨论过了。

捕捉异常后,如果想继续执行抛出异常后面紧接着的代码,需要清晰知道抛出点的上下文信息,否则就无法保证继续执行的正确性。然而,抛出点的上下文信息对于 catch 语句块来说是很难获取的,这就带来了恢复执行的不确定性。

如果继续一意孤行,为了解决不确定性,那么就需要加入大量的辅助代码,来维持抛出点和异常捕获点的联系。这种强连接性,破坏了目前异常处理机制的解耦特性,维护起来也会变得非常困难。

因此,C++ 设计之初就否定了在异常处理机制中加入恢复执行的可能性。

在实际的编程实践中,如果程序设计人员不希望程序业务流程被突然打断,可以在抛出异常之前先检查并尝试解决问题,只有在确实无法解决问题的情况下才抛出异常。

下面是一个简单的例子,演示了如何在抛出异常之前先尝试解决问题:

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() 尝试修复问题,只有在修复失败的情况下才会抛出异常。如果修复成功,程序将继续原有的流程。

假设修复成功,那么程序输出:

arduino 复制代码
This line will not be executed if exception is thrown
Program continues after catching the exception

假设修复失败,那么程序输出:

rust 复制代码
Caught an exception: Something went wrong and couldn't be fixed
Program continues after catching the exception

这种方式的代码更易于理解和维护,避免了异常处理中不必要的复杂性和不确定性。

异常处理的设计哲学

异常处理机制的设计哲学强调了代码的可读性、可维护性以及对异常情况的明确处理。抛出异常是一种信号,表明程序遇到了无法自动解决的问题,需要调用方来决定如何处理。在这种设计哲学下,恢复到抛出点并继续执行被认为是不合适的,因为这会增加代码的复杂性,并且容易导致不可预测的行为。

相关推荐
W23035765733 小时前
经典算法:最长上升子序列(LIS)深度解析 C++ 实现
开发语言·c++·算法
.Ashy.3 小时前
2026.4.11 蓝桥杯软件类C/C++ G组山东省赛 小记
c语言·c++·蓝桥杯
minji...4 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
CoderCodingNo6 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
hetao17338377 小时前
2026-04-09~12 hetao1733837 的刷题记录
c++·算法
6Hzlia7 小时前
【Hot 100 刷题计划】 LeetCode 136. 只出现一次的数字 | C++ 哈希表&异或基础解法
c++·算法·leetcode
汉克老师8 小时前
GESP2024年6月认证C++三级( 第二部分判断题(1-10))
c++·数组·位运算·补码·gesp三级·gesp3级
无限进步_9 小时前
【C++】只出现一次的数字 II:位运算的三种解法深度解析
数据结构·c++·ide·windows·git·算法·leetcode
小贾要学习9 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
哎嗨人生公众号10 小时前
手写求导公式,让轨迹优化性能飞升,150ms变成9ms
开发语言·c++·算法·机器人·自动驾驶