C++ 异常机制深度解析:从原理到实战的完整指南

核心价值: 掌握 C++ 异常处理的完整体系,从基础原理到高级应用,构建健壮可靠的现代 C++ 程序


异常处理是现代 C++ 编程中的重要机制,它改变了传统的错误处理方式,让程序能够优雅地应对运行时错误。不同于 C 语言的错误码模式,C++ 异常机制提供了更清晰、更安全的错误管理方案。

  • 深入理解异常机制的设计理念与运行原理
  • 掌握异常安全编程的核心技巧与最佳实践
  • 学会设计健壮的异常处理架构
  • 了解现代 C++ 中异常处理的性能优化策略

为什么需要异常机制?

想象你正在开发一个文件处理程序。使用传统的 C 语言错误处理方式,代码可能是这样的:

// C 语言的错误处理方式
int process_file(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) return ERROR_FILE_NOT_FOUND;    // 错误码1
    
    char* buffer = malloc(1024);
    if (!buffer) {
        fclose(file);
        return ERROR_OUT_OF_MEMORY;            // 错误码2
    }
    
    if (fread(buffer, 1024, 1, file) != 1) {
        free(buffer);
        fclose(file);
        return ERROR_READ_FAILED;              // 错误码3
    }
    
    // 还需要处理更多可能的错误...
    free(buffer);
    fclose(file);
    return SUCCESS;
}

这种方式存在明显问题:

问题类型 具体表现 影响
代码冗余 每个函数调用都要检查返回值 业务逻辑被错误处理代码淹没
资源管理复杂 多处手动释放资源 容易遗漏导致内存泄漏
错误信息有限 仅有数字错误码 调试困难,用户体验差
传播困难 逐层向上传递错误码 代码结构复杂,维护困难

C++ 异常机制优雅地解决了这些问题:

#include <iostream>
#include <fstream>
#include <memory>
#include <stdexcept>

class FileProcessor {
public:
    void processFile(const std::string& filename) {
        // 异常安全的文件处理
        std::ifstream file(filename);
        if (!file.is_open()) {
            throw std::runtime_error("无法打开文件: " + filename);
        }
        
        // RAII 自动管理内存
        auto buffer = std::make_unique<char[]>(1024);
        
        file.read(buffer.get(), 1024);
        if (file.fail() && !file.eof()) {
            throw std::runtime_error("文件读取失败");
        }
        
        // 处理数据...
        std::cout << "文件处理成功" << std::endl;
        
        // 资源自动释放,无需手动管理
    }
};

int main() {
    try {
        FileProcessor processor;
        processor.processFile("example.txt");
    }
    catch (const std::exception& e) {
        std::cout << "错误: " << e.what() << std::endl;
        // 统一的错误处理逻辑
    }
    
    return 0;
}

异常机制的核心优势:

  • 关注点分离: 业务逻辑与错误处理分离
  • 自动传播: 异常自动向上传播到能处理的地方
  • 丰富信息: 异常对象可携带详细的错误信息
  • 资源安全: 结合 RAII 确保资源正确释放

异常机制的核心原理

基础语法与概念

异常处理基于三个关键字:throwtrycatch。让我们通过一个简单例子理解其工作原理:

#include <iostream>
#include <string>

class DivisionError : public std::exception {
private:
    std::string message;
public:
    DivisionError(const std::string& msg) : message(msg) {}
    
    const char* what() const noexcept override {
        return message.c_str();
    }
};

double safeDivide(double a, double b) {
    if (b == 0.0) {
        // 抛出自定义异常
        throw DivisionError("除数不能为零 (a=" + std::to_string(a) + ")");
    }
    
    return a / b;
}

int main() {
    double x, y;
    std::cout << "请输入两个数字: ";
    std::cin >> x >> y;
    
    try {
        double result = safeDivide(x, y);
        std::cout << "结果: " << result << std::endl;
    }
    catch (const DivisionError& e) {
        std::cout << "计算错误: " << e.what() << std::endl;
        
        // 可以在这里进行恢复操作
        std::cout << "使用默认值 0.0 代替" << std::endl;
    }
    catch (const std::exception& e) {
        std::cout << "未知错误: " << e.what() << std::endl;
    }
    
    std::cout << "程序继续执行..." << std::endl;
    return 0;
}

执行流程分析:

  1. 正常执行: 当 b != 0 时,函数正常返回结果
  2. 异常触发: 当 b == 0 时,throw 创建异常对象并抛出
  3. 栈展开: 程序立即跳出当前函数,寻找匹配的 catch
  4. 异常处理: 找到匹配的 catch 后执行处理代码
  5. 继续执行: 处理完异常后,程序从 try-catch 块之后继续

栈展开机制深度解析

栈展开(Stack Unwinding)是异常机制的核心,它确保程序在异常传播过程中正确清理资源:

#include <iostream>
#include <string>

class ResourceTracker {
private:
    std::string name;
    int id;
    
public:
    ResourceTracker(const std::string& n, int i) : name(n), id(i) {
        std::cout << "创建资源: " << name << " (ID: " << id << ")" << std::endl;
    }
    
    ~ResourceTracker() {
        std::cout << "销毁资源: " << name << " (ID: " << id << ")" << std::endl;
    }
    
    void doWork() const {
        std::cout << "" << name << " 正在工作..." << std::endl;
    }
};

void level3Function() {
    ResourceTracker res3("Level3资源", 3);
    res3.doWork();
    
    std::cout << "Level3: 准备抛出异常" << std::endl;
    throw std::runtime_error("Level3 发生错误!");
    
    std::cout << "Level3: 这行代码不会执行" << std::endl; // 不会执行
}

void level2Function() {
    ResourceTracker res2("Level2资源", 2);
    res2.doWork();
    
    std::cout << "Level2: 调用 Level3" << std::endl;
    level3Function(); // 这里会抛出异常
    
    std::cout << "Level2: 这行代码不会执行" << std::endl; // 不会执行
}

void level1Function() {
    ResourceTracker res1("Level1资源", 1);
    res1.doWork();
    
    try {
        std::cout << "Level1: 调用 Level2" << std::endl;
        level2Function();
    }
    catch (const std::exception& e) {
        std::cout << "Level1 捕获异常: " << e.what() << std::endl;
    }
    
    std::cout << "Level1: 异常处理完毕,继续执行" << std::endl;
}

int main() {
    std::cout << "=== 栈展开示例 ===" << std::endl;
    level1Function();
    std::cout << "=== 程序正常结束 ===" << std::endl;
    
    return 0;
}

预期输出:

=== 栈展开示例 ===
创建资源: Level1资源 (ID: 1)
Level1资源 正在工作...
Level1: 调用 Level2
创建资源: Level2资源 (ID: 2)
Level2资源 正在工作...
Level2: 调用 Level3
创建资源: Level3资源 (ID: 3)
Level3资源 正在工作...
Level3: 准备抛出异常
销毁资源: Level3资源 (ID: 3)    ← 自动调用析构函数
销毁资源: Level2资源 (ID: 2)    ← 自动调用析构函数
Level1 捕获异常: Level3 发生错误!
Level1: 异常处理完毕,继续执行
销毁资源: Level1资源 (ID: 1)    ← 正常作用域结束
=== 程序正常结束 ===

栈展开的关键特性:

  1. 逆向销毁: 对象按创建顺序的逆序自动销毁
  2. 完整清理: 每个作用域内的局部对象都会正确析构
  3. 异常安全: 即使发生异常,资源也能得到正确释放

异常类型设计与匹配规则

标准异常类体系

C++ 标准库提供了完整的异常类层次结构:

#include <iostream>
#include <exception>
#include <stdexcept>
#include <memory>
#include <vector>

void demonstrateStandardExceptions() {
    std::cout << "=== 标准异常类型演示 ===" << std::endl;
    
    try {
        // 1. std::bad_alloc - 内存分配失败
        std::cout << "测试 std::bad_alloc:" << std::endl;
        // 尝试分配大量内存(可能失败)
        // std::vector<int> huge_vector(SIZE_MAX); // 取消注释可能触发 bad_alloc
        
        // 2. std::out_of_range - 越界访问
        std::cout << "测试 std::out_of_range:" << std::endl;
        std::vector<int> vec = {1, 2, 3};
        int value = vec.at(10); // 故意越界
        
    }
    catch (const std::bad_alloc& e) {
        std::cout << "内存分配异常: " << e.what() << std::endl;
    }
    catch (const std::out_of_range& e) {
        std::cout << "越界访问异常: " << e.what() << std::endl;
    }
    catch (const std::runtime_error& e) {
        std::cout << "运行时错误: " << e.what() << std::endl;
    }
    catch (const std::exception& e) {
        std::cout << "通用异常: " << e.what() << std::endl;
    }
    
    try {
        // 3. std::invalid_argument - 无效参数
        std::cout << "\n测试 std::invalid_argument:" << std::endl;
        std::stoi("not_a_number"); // 转换失败
    }
    catch (const std::invalid_argument& e) {
        std::cout << "参数无效异常: " << e.what() << std::endl;
    }
    
    try {
        // 4. std::logic_error - 逻辑错误
        std::cout << "\n测试 std::logic_error:" << std::endl;
        throw std::logic_error("程序逻辑错误");
    }
    catch (const std::logic_error& e) {
        std::cout << "逻辑错误异常: " << e.what() << std::endl;
    }
}

标准异常类继承关系图:

std::exception
├── std::bad_alloc
├── std::bad_cast
├── std::bad_exception
├── std::logic_error
│   ├── std::invalid_argument
│   ├── std::domain_error
│   ├── std::length_error
│   └── std::out_of_range
└── std::runtime_error
    ├── std::range_error
    ├── std::overflow_error
    └── std::underflow_error

自定义异常类设计

设计良好的自定义异常类应该包含足够的上下文信息:

#include <iostream>
#include <exception>
#include <string>
#include <sstream>
#include <chrono>
#include <iomanip>

// 基础异常类
class ApplicationException : public std::exception {
protected:
    std::string message;
    std::string timestamp;
    int error_code;
    
public:
    ApplicationException(const std::string& msg, int code = 0) 
        : message(msg), error_code(code) {
        // 记录异常发生的时间戳
        auto now = std::chrono::system_clock::now();
        auto time_t = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
        timestamp = ss.str();
    }
    
    const char* what() const noexcept override {
        return message.c_str();
    }
    
    int getErrorCode() const { return error_code; }
    const std::string& getTimestamp() const { return timestamp; }
    
    virtual std::string getDetailedInfo() const {
        std::stringstream ss;
        ss << "[" << timestamp << "] "
           << "错误代码: " << error_code << ", "
           << "消息: " << message;
        return ss.str();
    }
};

// 网络异常
class NetworkException : public ApplicationException {
private:
    std::string host;
    int port;
    
public:
    NetworkException(const std::string& msg, const std::string& h, int p, int code = 1001)
        : ApplicationException(msg, code), host(h), port(p) {}
    
    std::string getDetailedInfo() const override {
        std::stringstream ss;
        ss << ApplicationException::getDetailedInfo()
           << ", 主机: " << host << ":" << port;
        return ss.str();
    }
    
    const std::string& getHost() const { return host; }
    int getPort() const { return port; }
};

// 数据库异常
class DatabaseException : public ApplicationException {
private:
    std::string query;
    std::string database_name;
    
public:
    DatabaseException(const std::string& msg, const std::string& db, 
                     const std::string& sql = "", int code = 2001)
        : ApplicationException(msg, code), database_name(db), query(sql) {}
    
    std::string getDetailedInfo() const override {
        std::stringstream ss;
        ss << ApplicationException::getDetailedInfo()
           << ", 数据库: " << database_name;
        if (!query.empty()) {
            ss << ", 查询: " << query.substr(0, 50);
            if (query.length() > 50) ss << "...";
        }
        return ss.str();
    }
};

// 文件操作异常
class FileException : public ApplicationException {
private:
    std::string filename;
    std::string operation;
    
public:
    FileException(const std::string& msg, const std::string& file, 
                 const std::string& op, int code = 3001)
        : ApplicationException(msg, code), filename(file), operation(op) {}
    
    std::string getDetailedInfo() const override {
        std::stringstream ss;
        ss << ApplicationException::getDetailedInfo()
           << ", 文件: " << filename
           << ", 操作: " << operation;
        return ss.str();
    }
};

// 模拟各种异常场景
class SystemService {
public:
    void connectToServer(const std::string& host, int port) {
        if (host.empty()) {
            throw NetworkException("主机名不能为空", host, port, 1001);
        }
        if (port <= 0 || port > 65535) {
            throw NetworkException("端口号无效", host, port, 1002);
        }
        // 模拟连接失败
        throw NetworkException("连接超时", host, port, 1003);
    }
    
    void queryDatabase(const std::string& sql) {
        if (sql.find("DROP") != std::string::npos) {
            throw DatabaseException("禁止执行DROP操作", "production_db", sql, 2001);
        }
        // 模拟SQL语法错误
        throw DatabaseException("SQL语法错误", "production_db", sql, 2002);
    }
    
    void readFile(const std::string& filename) {
        if (filename.empty()) {
            throw FileException("文件名不能为空", filename, "read", 3001);
        }
        // 模拟文件不存在
        throw FileException("文件不存在", filename, "read", 3002);
    }
};

int main() {
    SystemService service;
    
    // 测试网络异常
    try {
        service.connectToServer("", 8080);
    }
    catch (const NetworkException& e) {
        std::cout << "网络异常捕获:" << std::endl;
        std::cout << e.getDetailedInfo() << std::endl;
        std::cout << "主机: " << e.getHost() << ", 端口: " << e.getPort() << std::endl;
    }
    
    std::cout << std::endl;
    
    // 测试数据库异常
    try {
        service.queryDatabase("DROP TABLE users");
    }
    catch (const DatabaseException& e) {
        std::cout << "数据库异常捕获:" << std::endl;
        std::cout << e.getDetailedInfo() << std::endl;
    }
    
    std::cout << std::endl;
    
    // 测试文件异常
    try {
        service.readFile("nonexistent.txt");
    }
    catch (const FileException& e) {
        std::cout << "文件异常捕获:" << std::endl;
        std::cout << e.getDetailedInfo() << std::endl;
    }
    
    // 使用基类捕获所有自定义异常
    std::cout << "\n=== 使用基类统一处理 ===" << std::endl;
    
    std::vector<std::function<void()>> operations = {
        []() { SystemService().connectToServer("invalid", -1); },
        []() { SystemService().queryDatabase("SELECT * FROM"); },
        []() { SystemService().readFile(""); }
    };
    
    for (size_t i = 0; i < operations.size(); ++i) {
        try {
            operations[i]();
        }
        catch (const ApplicationException& e) {
            std::cout << "操作 " << (i + 1) << " 失败: " << e.getDetailedInfo() << std::endl;
        }
    }
    
    return 0;
}

异常安全编程实践

异常安全是现代 C++ 编程的核心要求。根据异常安全的保证级别,可以分为三个层次:

异常安全保证级别

安全级别 说明 特点
基本保证 异常发生时程序处于有效状态 无资源泄漏,但对象状态可能改变
强保证 异常发生时程序状态不变 要么成功,要么回滚到原始状态
不抛异常保证 操作绝不抛出异常 通常用于析构函数和交换操作

RAII 与智能指针

RAII(Resource Acquisition Is Initialization)是异常安全的基石:

#include <iostream>
#include <memory>
#include <fstream>
#include <vector>
#include <mutex>

// 1. 传统的不安全代码
class UnsafeClass {
public:
    void unsafeOperation() {
        int* ptr = new int[100];  // 可能的内存泄漏点
        
        // 如果这里抛出异常,ptr 永远不会被释放
        riskyFunction();
        
        delete[] ptr;  // 可能永远不会执行
    }
    
private:
    void riskyFunction() {
        throw std::runtime_error("Something went wrong!");
    }
};

// 2. 使用 RAII 的安全代码
class SafeClass {
public:
    void safeOperation() {
        // 使用智能指针自动管理内存
        auto ptr = std::make_unique<int[]>(100);
        
        // 无论是否抛出异常,ptr 都会自动释放
        riskyFunction();
        
        // ptr 在作用域结束时自动释放
    }
    
private:
    void riskyFunction() {
        throw std::runtime_error("Something went wrong!");
    }
};

// 3. 复杂资源管理示例
class ResourceManager {
private:
    std::unique_ptr<std::ofstream> log_file;
    std::unique_ptr<std::mutex> mutex_ptr;
    std::vector<std::unique_ptr<int[]>> buffers;
    
public:
    ResourceManager(const std::string& log_path) {
        // 按顺序初始化资源
        mutex_ptr = std::make_unique<std::mutex>();
        log_file = std::make_unique<std::ofstream>(log_path);
        
        if (!log_file->is_open()) {
            throw std::runtime_error("无法打开日志文件: " + log_path);
        }
        
        // 预分配多个缓冲区
        for (int i = 0; i < 5; ++i) {
            buffers.push_back(std::make_unique<int[]>(1024));
        }
        
        std::cout << "资源管理器初始化成功" << std::endl;
    }
    
    // 异常安全的操作
    void processData(const std::string& data) {
        std::lock_guard<std::mutex> lock(*mutex_ptr);  // 自动锁管理
        
        try {
            // 模拟数据处理
            if (data.empty()) {
                throw std::invalid_argument("数据不能为空");
            }
            
            // 写入日志
            *log_file << "[" << getCurrentTime() << "] 处理数据: " << data << std::endl;
            log_file->flush();
            
            // 模拟可能失败的操作
            if (data == "error") {
                throw std::runtime_error("数据处理失败");
            }
            
            std::cout << "数据处理成功: " << data << std::endl;
        }
        catch (...) {
            // 记录错误日志
            *log_file << "[" << getCurrentTime() << "] 错误: 数据处理失败" << std::endl;
            log_file->flush();
            throw; // 重新抛出异常
        }
        // lock 在作用域结束时自动释放
    }
    
    ~ResourceManager() {
        std::cout << "资源管理器析构,释放所有资源" << std::endl;
        // 智能指针自动处理资源释放
    }
    
private:
    std::string getCurrentTime() const {
        auto now = std::chrono::system_clock::now();
        auto time_t = std::chrono::system_clock::to_time_t(now);
        std::stringstream ss;
        ss << std::put_time(std::localtime(&time_t), "%H:%M:%S");
        return ss.str();
    }
};

void demonstrateResourceManagement() {
    std::cout << "=== 资源管理演示 ===" << std::endl;
    
    try {
        ResourceManager manager("process.log");
        
        // 正常处理
        manager.processData("valid_data_1");
        manager.processData("valid_data_2");
        
        // 触发异常
        manager.processData("error");
        
    } // manager 在这里自动析构,释放所有资源
    catch (const std::exception& e) {
        std::cout << "捕获异常: " << e.what() << std::endl;
    }
    
    std::cout << "资源管理演示结束" << std::endl;
}

异常安全的容器操作

#include <vector>
#include <algorithm>
#include <stdexcept>

template<typename T>
class SafeVector {
private:
    std::vector<T> data;
    
public:
    // 强异常安全保证的插入操作
    void safeInsert(const T& value) {
        // 创建临时副本
        std::vector<T> temp_data = data;
        
        try {
            temp_data.push_back(value);
            // 只有成功后才替换原数据
            data = std::move(temp_data);
        }
        catch (...) {
            // 如果失败,data 保持不变
            throw;
        }
    }
    
    // 异常安全的批量操作
    template<typename Iterator>
    void safeBatchInsert(Iterator first, Iterator last) {
        std::vector<T> temp_data = data;
        
        try {
            // 预先计算需要的容量,减少重分配
            size_t distance = std::distance(first, last);
            temp_data.reserve(temp_data.size() + distance);
            
            // 批量插入
            for (auto it = first; it != last; ++it) {
                temp_data.push_back(*it);
            }
            
            // 成功后替换
            data = std::move(temp_data);
        }
        catch (...) {
            // 失败时 data 保持原状
            throw;
        }
    }
    
    // 提供基本访问接口
    size_t size() const { return data.size(); }
    const T& at(size_t index) const { return data.at(index); }
    
    // 安全的清空操作(不抛异常保证)
    void clear() noexcept {
        data.clear();
    }
};

void demonstrateSafeContainer() {
    std::cout << "\n=== 异常安全容器演示 ===" << std::endl;
    
    SafeVector<std::string> safe_vec;
    
    try {
        // 正常插入
        safe_vec.safeInsert("item1");
        safe_vec.safeInsert("item2");
        std::cout << "插入成功,当前大小: " << safe_vec.size() << std::endl;
        
        // 批量插入
        std::vector<std::string> batch = {"item3", "item4", "item5"};
        safe_vec.safeBatchInsert(batch.begin(), batch.end());
        std::cout << "批量插入成功,当前大小: " << safe_vec.size() << std::endl;
        
        // 访问元素
        for (size_t i = 0; i < safe_vec.size(); ++i) {
            std::cout << "  [" << i << "] = " << safe_vec.at(i) << std::endl;
        }
        
    }
    catch (const std::exception& e) {
        std::cout << "容器操作异常: " << e.what() << std::endl;
    }
}

int main() {
    demonstrateResourceManagement();
    demonstrateSafeContainer();
    
    return 0;
}

高级异常处理技术

异常重新抛出与异常链

有时需要在捕获异常后添加额外信息,然后重新抛出:

#include <iostream>
#include <exception>
#include <stack>

// 异常上下文信息
class ExceptionContext {
private:
    std::stack<std::string> call_stack;
    std::string operation_context;
    
public:
    void pushContext(const std::string& context) {
        call_stack.push(context);
    }
    
    void popContext() {
        if (!call_stack.empty()) {
            call_stack.pop();
        }
    }
    
    void setOperationContext(const std::string& context) {
        operation_context = context;
    }
    
    std::string getFullContext() const {
        std::string result = "调用栈:\n";
        std::stack<std::string> temp = call_stack;
        std::vector<std::string> stack_items;
        
        while (!temp.empty()) {
            stack_items.push_back(temp.top());
            temp.pop();
        }
        
        for (auto it = stack_items.rbegin(); it != stack_items.rend(); ++it) {
            result += "  -> " + *it + "\n";
        }
        
        if (!operation_context.empty()) {
            result += "操作上下文: " + operation_context;
        }
        
        return result;
    }
};

// 全局异常上下文(实际项目中可能使用线程局部存储)
thread_local ExceptionContext g_exception_context;

// RAII 上下文管理器
class ContextGuard {
public:
    ContextGuard(const std::string& context) {
        g_exception_context.pushContext(context);
    }
    
    ~ContextGuard() {
        g_exception_context.popContext();
    }
};

// 增强的异常类
class EnhancedException : public std::exception {
private:
    std::string message;
    std::string context;
    std::unique_ptr<std::exception> nested_exception;
    
public:
    EnhancedException(const std::string& msg, const std::string& ctx = "") 
        : message(msg), context(ctx) {}
    
    // 包装另一个异常
    EnhancedException(const std::string& msg, const std::exception& nested) 
        : message(msg), nested_exception(std::make_unique<std::exception>(nested)) {}
    
    const char* what() const noexcept override {
        return message.c_str();
    }
    
    std::string getFullMessage() const {
        std::string full_msg = message;
        
        if (!context.empty()) {
            full_msg += "\n上下文: " + context;
        }
        
        if (nested_exception) {
            full_msg += "\n原因: " + std::string(nested_exception->what());
        }
        
        return full_msg;
    }
    
    bool hasNestedException() const {
        return nested_exception != nullptr;
    }
};

// 业务逻辑层
class DataProcessor {
public:
    void processRecord(int record_id) {
        ContextGuard guard("DataProcessor::processRecord(id=" + std::to_string(record_id) + ")");
        
        try {
            validateRecord(record_id);
            transformData(record_id);
            saveResult(record_id);
        }
        catch (const std::exception& e) {
            // 添加业务上下文信息后重新抛出
            g_exception_context.setOperationContext("处理记录ID: " + std::to_string(record_id));
            throw EnhancedException("数据处理失败", e);
        }
    }
    
private:
    void validateRecord(int record_id) {
        ContextGuard guard("DataProcessor::validateRecord");
        
        if (record_id <= 0) {
            throw std::invalid_argument("记录ID必须大于0");
        }
        
        if (record_id == 999) {
            throw std::runtime_error("记录ID 999 为测试保留ID");
        }
    }
    
    void transformData(int record_id) {
        ContextGuard guard("DataProcessor::transformData");
        
        if (record_id == 500) {
            throw std::runtime_error("数据转换失败:缺少必要字段");
        }
        
        std::cout << "数据转换成功 (ID: " << record_id << ")" << std::endl;
    }
    
    void saveResult(int record_id) {
        ContextGuard guard("DataProcessor::saveResult");
        
        if (record_id == 777) {
            throw std::runtime_error("数据库连接失败");
        }
        
        std::cout << "结果保存成功 (ID: " << record_id << ")" << std::endl;
    }
};

// 服务层
class DataService {
public:
    void processBatch(const std::vector<int>& record_ids) {
        ContextGuard guard("DataService::processBatch");
        
        DataProcessor processor;
        int successful = 0;
        int failed = 0;
        
        for (int id : record_ids) {
            try {
                processor.processRecord(id);
                successful++;
            }
            catch (const EnhancedException& e) {
                failed++;
                std::cout << "处理失败:\n" << e.getFullMessage() << std::endl;
                std::cout << g_exception_context.getFullContext() << std::endl;
                std::cout << "---" << std::endl;
            }
            catch (const std::exception& e) {
                failed++;
                std::cout << "未知错误: " << e.what() << std::endl;
                std::cout << "---" << std::endl;
            }
        }
        
        std::cout << "\n📊 批处理结果: 成功 " << successful 
                  << ", 失败 " << failed << std::endl;
    }
};

int main() {
    std::cout << "=== 异常重新抛出与上下文信息演示 ===" << std::endl;
    
    DataService service;
    
    // 测试不同的异常情况
    std::vector<int> test_records = {100, -1, 500, 200, 777, 999, 300};
    
    service.processBatch(test_records);
    
    return 0;
}

现代 C++ 异常处理最佳实践

#include <iostream>
#include <exception>
#include <functional>
#include <optional>
#include <variant>

// 1. 使用 std::optional 避免异常
class SafeCalculator {
public:
    std::optional<double> safeDivide(double a, double b) noexcept {
        if (b == 0.0) {
            return std::nullopt;  // 返回空值而不是抛出异常
        }
        return a / b;
    }
    
    std::optional<double> safeSqrt(double x) noexcept {
        if (x < 0.0) {
            return std::nullopt;
        }
        return std::sqrt(x);
    }
};

// 2. 使用 std::variant 表示结果或错误
template<typename T>
using Result = std::variant<T, std::string>;  // 成功值或错误消息

class ModernCalculator {
public:
    Result<double> divide(double a, double b) noexcept {
        if (b == 0.0) {
            return std::string("除数不能为零");
        }
        return a / b;
    }
    
    Result<double> chainedOperation(double x, double y) noexcept {
        auto div_result = divide(x, y);
        
        // 使用 std::visit 处理 variant
        return std::visit([](auto&& arg) -> Result<double> {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, std::string>) {
                return arg;  // 传播错误
            } else {
                // 继续计算
                double value = arg;
                if (value < 0) {
                    return std::string("中间结果不能为负数");
                }
                return value * 2;
            }
        }, div_result);
    }
};

// 3. 异常安全的资源管理模板
template<typename Resource, typename Deleter>
class RAIIWrapper {
private:
    Resource resource;
    Deleter deleter;
    bool valid;
    
public:
    template<typename... Args>
    RAIIWrapper(Deleter del, Args&&... args) 
        : resource(std::forward<Args>(args)...), deleter(std::move(del)), valid(true) {}
    
    ~RAIIWrapper() {
        if (valid) {
            deleter(resource);
        }
    }
    
    // 禁止复制,允许移动
    RAIIWrapper(const RAIIWrapper&) = delete;
    RAIIWrapper& operator=(const RAIIWrapper&) = delete;
    
    RAIIWrapper(RAIIWrapper&& other) noexcept 
        : resource(std::move(other.resource)), 
          deleter(std::move(other.deleter)), 
          valid(other.valid) {
        other.valid = false;
    }
    
    Resource& get() { return resource; }
    const Resource& get() const { return resource; }
    
    Resource* operator->() { return &resource; }
    const Resource* operator->() const { return &resource; }
    
    Resource& operator*() { return resource; }
    const Resource& operator*() const { return resource; }
};

// 4. 异常安全的工厂函数
template<typename T>
auto make_safe_resource(T resource, std::function<void(T)> cleanup) {
    return RAIIWrapper<T, std::function<void(T)>>(std::move(cleanup), std::move(resource));
}

void demonstrateModernExceptionHandling() {
    std::cout << "=== 现代异常处理演示 ===" << std::endl;
    
    // 使用 std::optional
    SafeCalculator safe_calc;
    
    auto result1 = safe_calc.safeDivide(10.0, 2.0);
    if (result1) {
        std::cout << "安全除法结果: " << *result1 << std::endl;
    }
    
    auto result2 = safe_calc.safeDivide(10.0, 0.0);
    if (!result2) {
        std::cout << "除法失败:除数为零" << std::endl;
    }
    
    // 使用 Result<T> variant
    ModernCalculator modern_calc;
    
    auto calc_result = modern_calc.chainedOperation(20.0, 4.0);
    std::visit([](auto&& arg) {
        using T = std::decay_t<decltype(arg)>;
        if constexpr (std::is_same_v<T, std::string>) {
            std::cout << "计算错误: " << arg << std::endl;
        } else {
            std::cout << "计算结果: " << arg << std::endl;
        }
    }, calc_result);
    
    // 使用 RAII 包装器
    {
        auto file_handle = make_safe_resource(
            fopen("test.txt", "w"),
            [](FILE* f) { 
                if (f) {
                    std::cout << "关闭文件" << std::endl;
                    fclose(f); 
                }
            }
        );
        
        if (file_handle.get()) {
            fprintf(file_handle.get(), "Hello, RAII!\n");
            std::cout << "文件写入成功" << std::endl;
        }
        // 文件自动关闭
    }
}

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

性能考量与优化策略

异常处理的性能特点

C++ 异常机制在性能方面有独特的特点:

#include <chrono>
#include <iostream>
#include <vector>

// 性能测试工具
class PerformanceTimer {
private:
    std::chrono::high_resolution_clock::time_point start_time;
    std::string operation_name;
    
public:
    PerformanceTimer(const std::string& name) : operation_name(name) {
        start_time = std::chrono::high_resolution_clock::now();
    }
    
    ~PerformanceTimer() {
        auto end_time = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
        std::cout << operation_name << " 耗时: " << duration.count() << " 微秒" << std::endl;
    }
};

// 不同错误处理方式的性能对比
class PerformanceComparison {
public:
    // 1. 使用异常处理
    int exceptionBasedDivision(int a, int b) {
        if (b == 0) {
            throw std::runtime_error("Division by zero");
        }
        return a / b;
    }
    
    // 2. 使用错误码
    enum class ErrorCode { Success, DivisionByZero };
    
    ErrorCode errorCodeBasedDivision(int a, int b, int& result) noexcept {
        if (b == 0) {
            return ErrorCode::DivisionByZero;
        }
        result = a / b;
        return ErrorCode::Success;
    }
    
    // 3. 使用 std::optional
    std::optional<int> optionalBasedDivision(int a, int b) noexcept {
        if (b == 0) {
            return std::nullopt;
        }
        return a / b;
    }
    
    void performanceTest() {
        const int iterations = 1000000;
        std::vector<std::pair<int, int>> test_data;
        
        // 准备测试数据(99.9% 正常情况,0.1% 异常情况)
        for (int i = 0; i < iterations; ++i) {
            if (i % 1000 == 0) {
                test_data.emplace_back(100, 0);  // 异常情况
            } else {
                test_data.emplace_back(100, 2);  // 正常情况
            }
        }
        
        std::cout << "=== 性能测试 (测试数据: " << iterations << " 次操作) ===" << std::endl;
        
        // 测试异常处理性能
        {
            PerformanceTimer timer("异常处理方式");
            int exception_count = 0;
            int success_count = 0;
            
            for (const auto& [a, b] : test_data) {
                try {
                    int result = exceptionBasedDivision(a, b);
                    success_count++;
                } catch (const std::exception&) {
                    exception_count++;
                }
            }
            
            std::cout << "  成功: " << success_count << ", 异常: " << exception_count << std::endl;
        }
        
        // 测试错误码性能
        {
            PerformanceTimer timer("错误码方式  ");
            int error_count = 0;
            int success_count = 0;
            
            for (const auto& [a, b] : test_data) {
                int result;
                auto error = errorCodeBasedDivision(a, b, result);
                if (error == ErrorCode::Success) {
                    success_count++;
                } else {
                    error_count++;
                }
            }
            
            std::cout << "  成功: " << success_count << ", 错误: " << error_count << std::endl;
        }
        
        // 测试 optional 性能
        {
            PerformanceTimer timer("Optional方式 ");
            int empty_count = 0;
            int success_count = 0;
            
            for (const auto& [a, b] : test_data) {
                auto result = optionalBasedDivision(a, b);
                if (result) {
                    success_count++;
                } else {
                    empty_count++;
                }
            }
            
            std::cout << "  成功: " << success_count << ", 空值: " << empty_count << std::endl;
        }
    }
};

性能测试结果分析:

错误处理方式 正常情况性能 异常情况性能 代码复杂度
异常机制 几乎无开销 相对较高开销 低(代码简洁)
错误码 轻微检查开销 低开销 高(需要逐层检查)
std::optional 轻微包装开销 低开销 中等

noexcept 规范与编译器优化

#include <iostream>
#include <vector>
#include <type_traits>

class NoexceptDemo {
public:
    // 1. 基本 noexcept 用法
    void guaranteedNoThrow() noexcept {
        // 这个函数承诺不会抛出异常
        std::cout << "这个函数不会抛出异常" << std::endl;
    }
    
    // 2. 条件 noexcept
    template<typename T>
    void conditionalNoexcept(T value) noexcept(std::is_nothrow_copy_constructible_v<T>) {
        T copy = value;  // 只有当 T 的拷贝构造不抛异常时,此函数才 noexcept
    }
    
    // 3. 移动构造函数中的 noexcept(重要!)
    class ResourceHolder {
    private:
        std::unique_ptr<int[]> data;
        size_t size;
        
    public:
        ResourceHolder(size_t s) : data(std::make_unique<int[]>(s)), size(s) {}
        
        // 移动构造函数应该是 noexcept 的
        ResourceHolder(ResourceHolder&& other) noexcept 
            : data(std::move(other.data)), size(other.size) {
            other.size = 0;
        }
        
        // 移动赋值也应该是 noexcept 的
        ResourceHolder& operator=(ResourceHolder&& other) noexcept {
            if (this != &other) {
                data = std::move(other.data);
                size = other.size;
                other.size = 0;
            }
            return *this;
        }
        
        // 析构函数隐式是 noexcept 的
        ~ResourceHolder() = default;
        
        size_t getSize() const noexcept { return size; }
    };
    
    // 4. 检查函数是否 noexcept
    void checkNoexceptProperties() {
        std::cout << "\n=== noexcept 属性检查 ===" << std::endl;
        
        std::cout << "guaranteedNoThrow() is noexcept: " 
                  << std::boolalpha << noexcept(guaranteedNoThrow()) << std::endl;
        
        std::cout << "conditionalNoexcept<int>() is noexcept: " 
                  << noexcept(conditionalNoexcept<int>(42)) << std::endl;
                  
        std::cout << "conditionalNoexcept<std::vector<int>>() is noexcept: " 
                  << noexcept(conditionalNoexcept<std::vector<int>>({})) << std::endl;
        
        // 检查移动构造函数
        std::cout << "ResourceHolder move constructor is noexcept: " 
                  << std::is_nothrow_move_constructible_v<ResourceHolder> << std::endl;
    }
    
    // 5. 违反 noexcept 的后果
    void demonstrateNoexceptViolation() {
        std::cout << "\n=== noexcept 违反演示 ===" << std::endl;
        
        // 设置终止处理器
        std::set_terminate([]() {
            std::cout << "程序因为违反 noexcept 而终止!" << std::endl;
            std::abort();
        });
        
        try {
            // 这个函数声明为 noexcept 但实际会抛出异常
            auto violator = []() noexcept {
                std::cout << "即将违反 noexcept 承诺..." << std::endl;
                throw std::runtime_error("违反了 noexcept!");
            };
            
            // 注意:实际调用会导致程序终止
            // violator(); // 取消注释会导致程序终止
            
            std::cout << "上面的调用被注释掉了,否则程序会终止" << std::endl;
        }
        catch (...) {
            std::cout << "这里不会被执行,因为 noexcept 函数抛异常会直接终止程序" << std::endl;
        }
    }
};

// 6. 容器操作中 noexcept 的重要性
void demonstrateContainerOptimization() {
    std::cout << "\n=== 容器优化与 noexcept ===" << std::endl;
    
    class NonNoexceptType {
    public:
        NonNoexceptType() = default;
        NonNoexceptType(const NonNoexceptType&) = default;
        // 移动构造函数没有 noexcept
        NonNoexceptType(NonNoexceptType&&) { /* 可能抛异常 */ }
    };
    
    class NoexceptType {
    public:
        NoexceptType() = default;
        NoexceptType(const NoexceptType&) = default;
        // 移动构造函数有 noexcept
        NoexceptType(NoexceptType&&) noexcept = default;
    };
    
    std::cout << "NonNoexceptType move is noexcept: " 
              << std::is_nothrow_move_constructible_v<NonNoexceptType> << std::endl;
    std::cout << "NoexceptType move is noexcept: " 
              << std::is_nothrow_move_constructible_v<NoexceptType> << std::endl;
    
    // 对于没有 noexcept 移动构造的类型,std::vector 可能使用拷贝而不是移动
    std::vector<NonNoexceptType> vec1(1000);
    std::cout << "NonNoexceptType 向量创建完成" << std::endl;
    
    std::vector<NoexceptType> vec2(1000);
    std::cout << "NoexceptType 向量创建完成(移动优化生效)" << std::endl;
}

int main() {
    PerformanceComparison perf_test;
    perf_test.performanceTest();
    
    NoexceptDemo demo;
    demo.checkNoexceptProperties();
    demo.demonstrateNoexceptViolation();
    
    demonstrateContainerOptimization();
    
    return 0;
}

实战案例:构建健壮的网络服务

让我们通过一个完整的网络服务示例,展示异常处理在实际项目中的应用:

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <map>
#include <thread>
#include <mutex>
#include <chrono>
#include <fstream>
#include <sstream>

// 1. 异常类层次设计
class ServiceException : public std::exception {
protected:
    std::string message;
    int error_code;
    std::chrono::system_clock::time_point timestamp;
    
public:
    ServiceException(const std::string& msg, int code) 
        : message(msg), error_code(code), timestamp(std::chrono::system_clock::now()) {}
    
    const char* what() const noexcept override { return message.c_str(); }
    int getErrorCode() const noexcept { return error_code; }
    auto getTimestamp() const noexcept { return timestamp; }
    
    virtual std::string getCategory() const { return "Service"; }
};

class NetworkException : public ServiceException {
public:
    NetworkException(const std::string& msg, int code = 1000) 
        : ServiceException(msg, code) {}
    std::string getCategory() const override { return "Network"; }
};

class DatabaseException : public ServiceException {
private:
    std::string query;
public:
    DatabaseException(const std::string& msg, const std::string& sql = "", int code = 2000) 
        : ServiceException(msg, code), query(sql) {}
    std::string getCategory() const override { return "Database"; }
    const std::string& getQuery() const { return query; }
};

class BusinessLogicException : public ServiceException {
public:
    BusinessLogicException(const std::string& msg, int code = 3000) 
        : ServiceException(msg, code) {}
    std::string getCategory() const override { return "Business"; }
};

// 2. 日志系统
class Logger {
private:
    std::mutex log_mutex;
    std::unique_ptr<std::ofstream> log_file;
    
public:
    Logger(const std::string& filename) {
        log_file = std::make_unique<std::ofstream>(filename, std::ios::app);
        if (!log_file->is_open()) {
            throw std::runtime_error("无法打开日志文件: " + filename);
        }
    }
    
    void log(const std::string& level, const std::string& message) noexcept {
        try {
            std::lock_guard<std::mutex> lock(log_mutex);
            auto now = std::chrono::system_clock::now();
            auto time_t = std::chrono::system_clock::to_time_t(now);
            
            *log_file << "[" << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") 
                      << "] [" << level << "] " << message << std::endl;
            log_file->flush();
        } catch (...) {
            // 日志失败不应该影响主程序
        }
    }
    
    void logException(const ServiceException& e) noexcept {
        std::stringstream ss;
        ss << "异常 [" << e.getCategory() << ":" << e.getErrorCode() 
           << "] " << e.what();
        log("ERROR", ss.str());
    }
    
    ~Logger() = default; // 智能指针自动处理文件关闭
};

// 3. 数据库连接管理
class DatabaseManager {
private:
    std::map<std::string, std::string> connection_params;
    bool connected = false;
    Logger& logger;
    
public:
    DatabaseManager(Logger& log) : logger(log) {
        // 模拟连接参数
        connection_params["host"] = "localhost";
        connection_params["port"] = "5432";
        connection_params["database"] = "myapp";
    }
    
    void connect() {
        if (connected) return;
        
        try {
            logger.log("INFO", "正在连接数据库...");
            
            // 模拟连接过程
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            
            // 模拟连接失败的情况
            static int connection_attempts = 0;
            connection_attempts++;
            
            if (connection_attempts % 5 == 0) {
                throw NetworkException("数据库连接超时", 1001);
            }
            
            connected = true;
            logger.log("INFO", "数据库连接成功");
            
        } catch (const NetworkException&) {
            logger.log("ERROR", "数据库连接失败");
            throw; // 重新抛出,让上层处理
        }
    }
    
    std::string executeQuery(const std::string& sql) {
        if (!connected) {
            throw DatabaseException("数据库未连接", sql, 2001);
        }
        
        try {
            logger.log("DEBUG", "执行查询: " + sql);
            
            // 模拟SQL执行
            if (sql.find("SELECT") == 0) {
                return "查询结果: {data: 'sample'}";
            } else if (sql.find("INSERT") == 0) {
                return "插入成功: 1 row affected";
            } else {
                throw DatabaseException("不支持的SQL操作", sql, 2002);
            }
            
        } catch (const DatabaseException&) {
            throw; // 重新抛出数据库异常
        } catch (const std::exception& e) {
            // 包装未知异常
            throw DatabaseException("SQL执行失败: " + std::string(e.what()), sql, 2003);
        }
    }
    
    ~DatabaseManager() {
        if (connected) {
            logger.log("INFO", "断开数据库连接");
        }
    }
};

// 4. 业务服务层
class UserService {
private:
    DatabaseManager& db_manager;
    Logger& logger;
    
public:
    UserService(DatabaseManager& db, Logger& log) : db_manager(db), logger(log) {}
    
    std::string createUser(const std::string& username, const std::string& email) {
        if (username.empty() || email.empty()) {
            throw BusinessLogicException("用户名和邮箱不能为空", 3001);
        }
        
        if (email.find("@") == std::string::npos) {
            throw BusinessLogicException("邮箱格式无效", 3002);
        }
        
        try {
            // 检查用户是否已存在
            std::string check_sql = "SELECT id FROM users WHERE username = '" + username + "'";
            std::string result = db_manager.executeQuery(check_sql);
            
            if (result.find("sample") != std::string::npos) {
                throw BusinessLogicException("用户名已存在: " + username, 3003);
            }
            
            // 创建新用户
            std::string insert_sql = "INSERT INTO users (username, email) VALUES ('" 
                                   + username + "', '" + email + "')";
            std::string insert_result = db_manager.executeQuery(insert_sql);
            
            logger.log("INFO", "用户创建成功: " + username);
            return "用户创建成功: " + username;
            
        } catch (const DatabaseException& e) {
            logger.logException(e);
            throw BusinessLogicException("用户创建失败: " + std::string(e.what()), 3004);
        }
    }
    
    std::string getUserInfo(const std::string& username) {
        if (username.empty()) {
            throw BusinessLogicException("用户名不能为空", 3005);
        }
        
        try {
            std::string sql = "SELECT * FROM users WHERE username = '" + username + "'";
            return db_manager.executeQuery(sql);
            
        } catch (const DatabaseException& e) {
            logger.logException(e);
            throw BusinessLogicException("获取用户信息失败", 3006);
        }
    }
};

// 5. Web 服务层
class WebService {
private:
    std::unique_ptr<Logger> logger;
    std::unique_ptr<DatabaseManager> db_manager;
    std::unique_ptr<UserService> user_service;
    
public:
    WebService() {
        try {
            // 初始化组件,注意初始化顺序
            logger = std::make_unique<Logger>("service.log");
            db_manager = std::make_unique<DatabaseManager>(*logger);
            user_service = std::make_unique<UserService>(*db_manager, *logger);
            
            logger->log("INFO", "Web服务初始化完成");
            
        } catch (const std::exception& e) {
            std::cerr << "服务初始化失败: " << e.what() << std::endl;
            throw;
        }
    }
    
    std::string handleRequest(const std::string& method, const std::string& path, 
                            const std::map<std::string, std::string>& params) {
        try {
            logger->log("INFO", "处理请求: " + method + " " + path);
            
            // 确保数据库连接
            db_manager->connect();
            
            if (method == "POST" && path == "/users") {
                auto username_it = params.find("username");
                auto email_it = params.find("email");
                
                if (username_it == params.end() || email_it == params.end()) {
                    throw BusinessLogicException("缺少必要参数", 3007);
                }
                
                return user_service->createUser(username_it->second, email_it->second);
                
            } else if (method == "GET" && path.find("/users/") == 0) {
                std::string username = path.substr(7); // 移除 "/users/" 前缀
                return user_service->getUserInfo(username);
                
            } else {
                throw BusinessLogicException("不支持的请求路径: " + path, 3008);
            }
            
        } catch (const BusinessLogicException& e) {
            logger->logException(e);
            return createErrorResponse(e.getErrorCode(), e.what());
            
        } catch (const DatabaseException& e) {
            logger->logException(e);
            return createErrorResponse(500, "数据库服务暂时不可用");
            
        } catch (const NetworkException& e) {
            logger->logException(e);
            return createErrorResponse(503, "网络服务不可用,请稍后重试");
            
        } catch (const std::exception& e) {
            logger->log("ERROR", "未处理的异常: " + std::string(e.what()));
            return createErrorResponse(500, "内部服务器错误");
        }
    }
    
private:
    std::string createErrorResponse(int code, const std::string& message) {
        return "{\"error\": {\"code\": " + std::to_string(code) + 
               ", \"message\": \"" + message + "\"}}";
    }
};

// 6. 模拟客户端请求
void simulateRequests() {
    std::cout << "=== 网络服务异常处理演示 ===" << std::endl;
    
    try {
        WebService service;
        
        // 模拟各种请求
        std::vector<std::tuple<std::string, std::string, std::map<std::string, std::string>>> requests = {
            {"POST", "/users", {{"username", "alice"}, {"email", "alice@example.com"}}},
            {"POST", "/users", {{"username", "bob"}}}, // 缺少邮箱
            {"POST", "/users", {{"username", "charlie"}, {"email", "invalid-email"}}}, // 无效邮箱
            {"GET", "/users/alice", {}},
            {"GET", "/users/", {}}, // 空用户名
            {"DELETE", "/users/alice", {}}, // 不支持的方法
        };
        
        for (size_t i = 0; i < requests.size(); ++i) {
            const auto& [method, path, params] = requests[i];
            
            std::cout << "\n--- 请求 " << (i + 1) << " ---" << std::endl;
            std::cout << "方法: " << method << ", 路径: " << path << std::endl;
            
            std::string response = service.handleRequest(method, path, params);
            std::cout << "响应: " << response << std::endl;
        }
        
    } catch (const std::exception& e) {
        std::cout << "服务启动失败: " << e.what() << std::endl;
    }
}

int main() {
    simulateRequests();
    
    std::cout << "\n服务演示完成,请查看 service.log 获取详细日志" << std::endl;
    
    return 0;
}

异常处理最佳实践总结

设计原则

原则 说明 示例应用
失败快速原则 尽早发现并报告错误 参数验证、前置条件检查
异常安全性 保证资源不泄漏,状态一致 RAII、智能指针、事务性操作
信息丰富性 异常应包含足够的上下文信息 自定义异常类、错误码、时间戳
关注点分离 业务逻辑与错误处理分离 try-catch 块、异常传播

何时使用异常 vs 其他错误处理方式

// 适合使用异常的场景
class BankAccount {
    double balance;
public:
    void withdraw(double amount) {
        if (amount > balance) {
            // 业务规则违反,使用异常
            throw InsufficientFundsException(balance, amount);
        }
        balance -= amount;
    }
};

// 考虑使用返回值的场景
class Parser {
public:
    std::optional<int> tryParseInt(const std::string& str) noexcept {
        // 解析失败是常见情况,不是异常情况
        try {
            return std::stoi(str);
        } catch (...) {
            return std::nullopt;
        }
    }
};

// 不适合使用异常的场景
class FileReader {
public:
    bool hasNextLine() const noexcept {
        // 到达文件末尾是正常情况,不应抛出异常
        return !eof;
    }
};

性能优化建议

  1. 异常路径优化: 保持异常路径简单,避免复杂的异常处理逻辑
  2. noexcept 标记: 对不会抛异常的函数使用 noexcept
  3. 移动语义: 确保移动构造函数和移动赋值是 noexcept
  4. 异常对象优化: 避免在异常对象中进行昂贵的操作

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐