跳转到内容

C++ 异常处理最佳实践

来自代码酷

C++异常处理最佳实践[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

异常处理是C++中用于管理程序运行时错误的一种机制,它允许开发者将错误处理代码与正常业务逻辑分离,从而提高代码的可读性和可维护性。C++通过trycatchthrow关键字实现异常处理。本章将介绍异常处理的基本原理、最佳实践以及实际应用场景。

基本语法[编辑 | 编辑源代码]

C++异常处理的核心结构如下:

try {
    // 可能抛出异常的代码
    throw SomeException("Error message");
} catch (const SomeException& ex) {
    // 处理特定异常
    std::cerr << ex.what() << std::endl;
} catch (...) {
    // 捕获所有未处理的异常
    std::cerr << "Unknown exception occurred" << std::endl;
}

示例:除零错误处理[编辑 | 编辑源代码]

以下代码演示如何捕获除零异常:

#include <iostream>
#include <stdexcept>

double divide(int a, int b) {
    if (b == 0) {
        throw std::invalid_argument("Division by zero!");
    }
    return static_cast<double>(a) / b;
}

int main() {
    try {
        std::cout << divide(10, 0) << std::endl;
    } catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
    }
    return 0;
}

输出:

Error: Division by zero!

最佳实践[编辑 | 编辑源代码]

1. 优先使用标准异常[编辑 | 编辑源代码]

C++标准库提供了一系列预定义异常(如std::runtime_errorstd::invalid_argument),应优先使用它们而非自定义异常。

2. 避免捕获所有异常(catch(...))[编辑 | 编辑源代码]

除非必要,否则避免使用catch(...),因为它会隐藏未预期的错误。若必须使用,确保记录异常信息:

catch (...) {
    std::cerr << "Unexpected error occurred" << std::endl;
    throw; // 重新抛出异常
}

3. 异常安全保证[编辑 | 编辑源代码]

函数应提供以下三种异常安全保证之一:

  • 基本保证:程序状态保持一致,无资源泄漏。
  • 强保证:操作要么完全成功,要么回滚到初始状态。
  • 不抛保证:函数承诺不抛出任何异常(用noexcept标记)。

4. 资源管理(RAII)[编辑 | 编辑源代码]

使用资源获取即初始化(RAII)技术管理资源(如文件、内存),确保异常发生时资源被正确释放。例如:

#include <fstream>
#include <iostream>

void writeToFile(const std::string& filename) {
    std::ofstream file(filename);
    if (!file) {
        throw std::runtime_error("Failed to open file");
    }
    file << "Data"; // 若抛出异常,file的析构函数会自动关闭文件
}

实际案例:文件处理[编辑 | 编辑源代码]

以下是一个结合RAII和异常处理的文件读取示例:

#include <fstream>
#include <iostream>
#include <vector>
#include <stdexcept>

std::vector<std::string> readLines(const std::string& filename) {
    std::ifstream file(filename);
    if (!file) {
        throw std::runtime_error("Cannot open file: " + filename);
    }

    std::vector<std::string> lines;
    std::string line;
    while (std::getline(file, line)) {
        lines.push_back(line);
    }

    if (file.bad()) {
        throw std::runtime_error("Error while reading file");
    }
    return lines;
}

int main() {
    try {
        auto lines = readLines("example.txt");
        for (const auto& line : lines) {
            std::cout << line << std::endl;
        }
    } catch (const std::exception& ex) {
        std::cerr << "File error: " << ex.what() << std::endl;
    }
}

异常处理流程图[编辑 | 编辑源代码]

graph TD A[开始] --> B{可能抛出异常的代码} B -->|无异常| C[正常执行] B -->|抛出异常| D[匹配catch块] D --> E[异常处理] E --> F[继续执行或终止]

数学公式示例[编辑 | 编辑源代码]

若异常处理涉及概率计算(如错误率),可使用公式表示: P(error)=异常次数总操作次数

总结[编辑 | 编辑源代码]

  • 使用标准异常类型以提高代码可移植性。
  • 遵循RAII原则管理资源。
  • 明确函数的异常安全保证级别。
  • 在实际场景中(如文件I/O、网络请求)结合异常处理与日志记录。

通过以上实践,可以编写出健壮且易于维护的C++代码。