<exception> 是 C++ 标准库中与异常处理相关的头文件,它定义了异常类层次结构以及处理异常的基础设施。通过 <exception>,程序可以捕获和处理错误情况,提供统一的异常处理机制,从而提高代码的健壮性和可维护性。


目录

  1. 简介
  2. 标准异常类
  3. 异常处理机制
  4. 自定义异常
  5. 常见注意事项
  6. 结论

1. 简介

<exception> 提供了异常处理基础类和接口,使得 C++ 程序能以一致的方式抛出和捕获异常。通过这种机制,程序可以将错误信息向上传递,并在合适的地方处理异常情况,而不会导致程序崩溃。

在 C++ 中,异常处理通常依赖于三个关键字:throw 用于抛出异常,try 块包围可能抛出异常的代码,而 catch 块则用于捕获并处理异常。

要使用异常处理相关的功能,需要包含 <exception> 头文件:

#include <exception>


2. 标准异常类

2.1 std::exception

std::exception 是所有标准异常类的基类。它定义了一个虚函数 what(),用于返回描述异常的 C 风格字符串。该函数通常在异常捕获后用于获取错误信息。

示例:

#include <iostream>
#include <exception>

int main() {
    try {
        throw std::exception();
    } catch (const std::exception& ex) {
        std::cout << "Caught exception: " << ex.what() << std::endl;
    }
    return 0;
}

2.2 派生的异常类

C++ 标准库定义了许多派生自 std::exception 的异常类,常见的包括:

  • std::logic_error:表示程序逻辑错误,例如违反函数前置条件。
    • 派生类:std::invalid_argumentstd::domain_errorstd::length_errorstd::out_of_range
  • std::runtime_error:表示在运行时发生的错误,通常与系统资源相关。
    • 派生类:std::overflow_errorstd::underflow_error

示例:

#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("Runtime error occurred!");
    } catch (const std::exception& ex) {
        std::cout << "Caught exception: " << ex.what() << std::endl;
    }
    return 0;
}


3. 异常处理机制

3.1 throw、try 和 catch

异常处理使用三大关键字:

  • throw:用于抛出一个异常对象。
  • try:用于包围可能产生异常的代码块。
  • catch:用于捕获并处理抛出的异常。

示例:

#include <iostream>
#include <stdexcept>

void mightGoWrong() {
    // 抛出一个异常对象
    throw std::invalid_argument("Invalid argument provided!");
}

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

3.2 异常规范(已废弃)

C++ 早期版本曾提供异常规范(exception specifications),但在 C++11 之后,这一机制已被废弃,取而代之的是 noexcept 关键字,用于指明函数不会抛出异常。


4. 自定义异常

你可以通过继承 std::exception 或其派生类来自定义异常类型,并重写 what() 方法提供特定的错误信息。

示例:

#include <iostream>
#include <exception>
#include <string>

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

int main() {
    try {
        throw MyException("This is a custom exception!");
    } catch (const std::exception& ex) {
        std::cout << "Caught custom exception: " << ex.what() << std::endl;
    }
    return 0;
}


5. 常见注意事项

  • 异常安全性:编写代码时要确保资源正确释放,尽量使用 RAII 技术管理资源,以防止异常导致资源泄露。
  • 捕获方式:通常捕获异常时采用 const std::exception& 方式,以避免不必要的拷贝和切片问题。
  • 不要滥用异常:异常机制适用于处理不可恢复的错误或意外情况,不建议将异常用于控制程序的常规流程。
  • noexcept:对那些不会抛出异常的函数,建议使用 noexcept 修饰符,以帮助编译器进行优化,并提高程序的可靠性。

6. 结论

<exception> 为 C++ 程序提供了一个结构化的异常处理机制,通过统一的异常类层次结构,可以捕获并处理各种运行时错误。理解和正确使用 <exception> 中的异常类和处理机制,有助于构建更为健壮和安全的 C++ 应用程序。

推荐阅读: