C++函数异常是C++标准提供的错误处理机制,允许程序在运行过程中遇到错误时主动抛出异常,由对应的捕获模块处理错误,避免错误扩散导致程序非正常退出。相比传统的返回值判断错误处理方式,异常机制能够将错误信息和正常业务逻辑分离,让代码结构更清晰。

C++函数异常的核心组成
C++函数异常的实现依赖三个核心关键字,分别是throw、try、catch,三者配合完成异常的抛出、检测与捕获处理。
throw关键字
throw用于在函数内部检测到错误时抛出异常,可以抛出任意类型的异常值,常见的有整型、字符串、标准异常类型等。
try-catch块
try块包裹可能出现异常的代码逻辑,当try块内的代码抛出异常时,程序会跳转到对应的catch块执行处理逻辑。catch块需要声明要捕获的异常类型,匹配到对应类型才会执行。
基础异常处理示例
下面是一个简单的除法函数异常处理示例,当除数为0时抛出异常:
#include <iostream>
#include <stdexcept>
// 除法函数,除数为0时抛出异常
double divide(double a, double b) {
if (b == 0) {
// 抛出标准异常,提示除数不能为0
throw std::runtime_error("除数不能为0");
}
return a / b;
}
int main() {
double num1 = 10.0, num2 = 0.0;
try {
// 调用可能抛出异常的函数
double result = divide(num1, num2);
std::cout << "计算结果:" << result << std::endl;
} catch (const std::runtime_error& e) {
// 捕获运行时异常,输出错误信息
std::cout << "捕获到异常:" << e.what() << std::endl;
} catch (...) {
// 捕获所有其他类型的异常
std::cout << "捕获到未知异常" << std::endl;
}
return 0;
}函数异常规格说明
在C++中,可以在函数声明时指定异常规格,说明函数可能抛出的异常类型,帮助调用者提前了解函数的异常抛出情况。C++11之后推荐使用noexcept关键字标识函数是否抛出异常。
| 语法形式 | 含义 |
|---|---|
| void func() noexcept | 函数不会抛出任何异常 |
| void func() noexcept(false) | 函数可能抛出异常 |
| void func() throw(int, char) | 函数可能抛出int或char类型异常(C++11前用法,已不推荐) |
异常处理的注意事项
- 不要抛出析构函数中的异常,否则可能导致程序在栈展开时调用
std::terminate终止。 - 捕获异常时,尽量使用常引用捕获,避免不必要的拷贝,同时可以捕获到派生类异常。
- 异常抛出后如果没有被捕获,程序会调用
std::terminate终止运行,因此要确保关键逻辑都有对应的异常处理。 - 不要在异常处理的
catch块中再次抛出不相关的异常,避免错误处理逻辑混乱。
常见标准异常类型
C++标准库提供了一系列标准异常类型,定义在<stdexcept>头文件中,开发者可以直接使用这些类型抛出常见错误:
std::runtime_error:运行时错误,比如除数为0、文件打开失败等。std::logic_error:逻辑错误,比如参数无效、越界访问等。std::out_of_range:越界错误,比如访问容器超出有效范围。std::invalid_argument:无效参数错误,比如传入不符合要求的参数。
合理使用C++函数异常机制,能够让程序的错误处理更规范,减少因错误未处理导致的程序崩溃问题,提升代码的健壮性。