c++异常处理exception

在 C++ 中,异常处理(Exception Handling)是一种用于处理程序运行时错误的语言机制。它允许程序在检测到错误时,将控制权转移到预定义的错误处理代码,而无需通过函数返回值层层传递。


核心语法

try、catch 和 throw

C++ 异常处理主要由三个关键字构成:

  • throw:当检测到异常时,使用 throw 关键字抛出一个异常对象。
  • try:包含可能引发异常的代码块。
  • catch:紧跟在 try 块之后,用于捕获并处理特定类型的异常。如果未找到匹配的 catch 块,程序会调用 std::terminate 终止执行。
#include <stdexcept>
#include <iostream>

void MyFunc(int c) {
    if (c > 100) {
        throw std::invalid_argument("参数过大"); // 抛出异常
    }
}

int main() {
    try {
        MyFunc(256);
    }
    catch (const std::invalid_argument& e) { // 捕获异常
        std::cerr << "捕获到异常: " << e.what() << std::endl;
    }
    return 0;
}

在这里插入图片描述

标准异常类

C++ 标准库提供了一系列异常类,它们都继承自基类 std::exception。建议在抛出异常时,直接或间接派生自该基类。

常见的标准异常包括:

std::logic_error:表示程序中的逻辑错误(如无效参数 invalid_argument、越界 out_of_range)。
std::runtime_error:表示仅在运行时才能检测到的错误(如文件未找到)。
std::bad_alloc:当内存分配(如 new)失败时抛出。

所有标准异常类都提供了一个 what() 虚函数,用于返回描述异常的 C 风格字符串。

3. 栈展开(Stack Unwinding)

当异常被抛出后,C++ 运行时会执行“栈展开”机制。系统会从抛出异常的位置开始,逆序析构当前作用域内所有已经构造的局部对象,然后逐层向上回溯调用栈,直到找到匹配的 catch 块。这一机制确保了资源的自动清理。

C++ 异常处理最佳实践

为了编写安全、健壮的 C++ 代码,需要遵循以下准则:

  • 使用 RAII 管理资源:C++ 不提供 finally 块。应使用“资源获取即初始化”(RAII)惯用法(如智能指针 std::unique_ptr 或 std::shared_ptr),确保在栈展开时资源能被自动释放,避免内存泄漏。
  • 通过值抛出,通过引用捕获:抛出异常时按值传递,捕获时使用常量引用(如 catch (const std::exception& e)),这可以避免对象切片(Object Slicing)问题并减少不必要的拷贝开销。
  • 禁止在析构函数中抛出异常:如果析构函数在栈展开期间抛出异常,会导致程序直接调用 std::terminate 崩溃。
  • 合理使用 noexcept:使用 noexcept 关键字明确标记不会抛出异常的函数。这有助于编译器优化,并防止意外异常逃逸。
  • 区分断言与异常:使用断言(assert)检查开发阶段不应发生的逻辑错误;使用异常处理运行时可能出现的、程序需要恢复或优雅退出的错误(如输入验证失败)。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐