【C++】异常处理:catch块执行后程序如何继续

文章目录

当异常被捕获后, catch块中的代码会正常执行 ,然后程序会 继续执行catch块之后的代码 (除非catch块中又抛出了新的异常或调用了exit等函数)。

1. 基本流程示例

cpp 复制代码
#include <iostream>

int main() {
    try {
        std::cout << "1. try块开始" << std::endl;
        throw std::runtime_error("测试异常");
        std::cout << "这行不会执行!" << std::endl;  // ❌ 被跳过
    }
    catch (const std::exception& e) {
        std::cout << "2. 捕获异常: " << e.what() << std::endl;
        // ✅ catch块内的代码会执行
    }
    
    std::cout << "3. catch块后的代码继续执行" << std::endl;
    return 0;
}
// 输出:
// 1. try块开始
// 2. 捕获异常: 测试异常
// 3. catch块后的代码继续执行

2. 不同情况分析

a) 重新抛出异常(throw;)

cpp 复制代码
try {
    throw std::runtime_error("原始异常");
}
catch (...) {
    std::cout << "捕获到异常,但重新抛出" << std::endl;
    throw;  // 重新抛出,后面的代码不会执行
    std::cout << "这行不会执行" << std::endl;
}
// catch块后的代码也不会执行

b) 抛出新异常

cpp 复制代码
try {
    throw 1;
}
catch (int e) {
    std::cout << "捕获int异常: " << e << std::endl;
    throw "新异常";  // 抛出新的异常
    // 后面的代码不会执行
}
catch (const char* e) {
    std::cout << "捕获char*异常: " << e << std::endl;
}
std::cout << "这行会执行" << std::endl;

c) 函数中的异常处理

cpp 复制代码
#include <iostream>

void processData(int value) {
    if (value < 0) {
        throw std::invalid_argument("数值不能为负");
    }
    std::cout << "处理数值: " << value << std::endl;
}

int main() {
    std::cout << "程序开始" << std::endl;
    
    try {
        processData(-5);  // 抛出异常
        processData(10);  // ❌ 这行不会执行
    }
    catch (const std::exception& e) {
        std::cout << "错误: " << e.what() << std::endl;
        // ✅ catch块内的代码执行
    }
    
    processData(20);  // ✅ 这行会执行,因为异常已被处理
    
    std::cout << "程序结束" << std::endl;
    return 0;
}
// 输出:
// 程序开始
// 错误: 数值不能为负
// 处理数值: 20
// 程序结束

3. 多个catch块的情况

cpp 复制代码
try {
    throw std::string("字符串异常");
}
catch (int e) {
    std::cout << "捕获int: " << e << std::endl;
}
catch (const std::string& e) {
    std::cout << "捕获string: " << e << std::endl;
    // ✅ 这个catch块会执行
}
catch (...) {
    std::cout << "捕获未知异常" << std::endl;
}

std::cout << "继续执行..." << std::endl;

4. 嵌套异常处理

cpp 复制代码
#include <iostream>
#include <stdexcept>

void innerFunction() {
    try {
        throw std::runtime_error("内部错误");
    }
    catch (const std::exception& e) {
        std::cout << "内部处理: " << e.what() << std::endl;
        // 异常已在内部处理,不会传播到外部
    }
    std::cout << "内部函数继续执行" << std::endl;
}

void outerFunction() {
    try {
        innerFunction();
        std::cout << "外部函数继续执行" << std::endl;  // ✅ 会执行
    }
    catch (...) {
        std::cout << "外部捕获异常" << std::endl;  // ❌ 不会执行
    }
}

int main() {
    outerFunction();
    return 0;
}

5. 重要的特殊场景

a) catch块中返回

cpp 复制代码
bool process() {
    try {
        throw std::runtime_error("错误");
    }
    catch (...) {
        std::cout << "发生错误" << std::endl;
        return false;  // 从函数返回
    }
    
    std::cout << "这行不会执行" << std::endl;  // ❌ 因为已经return了
    return true;
}

b) 构造函数异常的特殊性

cpp 复制代码
class Test {
    int* ptr;
public:
    Test() : ptr(new int[100]) {
        throw std::runtime_error("构造失败");
        // 构造函数中的异常:
        // 1. 对象不会构造完成
        // 2. 成员ptr的内存会泄漏(需要智能指针解决)
    }
    ~Test() { delete[] ptr; }  // 不会被调用
};

c) 析构函数异常(极度危险)

cpp 复制代码
class BadClass {
public:
    ~BadClass() noexcept(false) {
        // 析构函数中抛异常极其危险
        throw std::exception();  // ❌ 可能导致程序terminate
    }
};

6. 最佳实践建议

cpp 复制代码
void safeProcessing() {
    std::ifstream file("data.txt");
    if (!file) {
        throw std::runtime_error("无法打开文件");
    }
    
    try {
        // 复杂的处理逻辑
        processFile(file);
    }
    catch (const std::ios_base::failure& e) {
        std::cerr << "IO错误: " << e.what() << std::endl;
        // 清理资源
        file.close();
        throw;  // 重新抛出给上层
    }
    catch (const std::exception& e) {
        std::cerr << "处理错误: " << e.what() << std::endl;
        // 继续执行其他逻辑或返回错误码
    }
    
    // 正常情况继续执行
    postProcessing();
}

关键总结

  1. catch块内的代码会执行
  2. catch块之后的代码也会执行(除非catch块中有return/throw/exit等)
  3. 异常抛出点之后的try块代码不会执行
  4. ⚠️ 异常必须在某处被捕获,否则程序终止
相关推荐
dear_bi_MyOnly17 分钟前
函数模块化:企业级项目高效之道
c++·后端·学习
Fcy64822 分钟前
Linux下 Socket编程 —— TCP网络编程
linux·网络·tcp/ip
码匠许师傅22 分钟前
【设计模式精讲】13.装饰器模式(Decorator)
c++·设计模式·uml·装饰器模式
IPdodo_32 分钟前
静态 IP 访问异常排查:403/429 归因与迁移验收
服务器·网络·数据库·python·网络协议·php·性能测试
ouynagda41 分钟前
HTTP协议与Socket网络编程笔记
网络·笔记·http
haerapi1 小时前
流式对话接口怎么选:SSE 与 WebSocket 的原理、实现和工程边界
网络·websocket·网络协议
OPEN-F1 小时前
C++综合实战:面向对象图书管理系统
开发语言·c++
砚凝霜1 小时前
【软考信息安全】第二章 网络攻击基础与常见技术方法
网络·安全·php
Raas1001 小时前
AI网关在架构中的位置?MAI Gateway(魔芋企业级AI网关)给出企业级答案
大数据·网络·人工智能·架构·gateway·ai网关·mai gateway
hflmwl81 小时前
Motrix电脑版官网免费下载,motrix服务器绿色版官方下载安装
运维·服务器·motrix