<stdexcept>
是 C++ 标准库中专门用于提供标准异常类的头文件。这些异常类继承自 std::exception
,为常见错误情况提供了具体的异常类型,使得程序可以抛出和捕获更具描述性的异常,从而提高代码的可读性和健壮性。
目录
1. 简介
<stdexcept>
定义了许多标准异常类,用于描述程序中可能发生的错误。相比直接使用 std::exception
,这些类能够更具体地表达错误类型,从而让异常处理更具语义。只需包含头文件:
#include <stdexcept>
2. 常见的标准异常类
标准异常类大致分为两类:逻辑错误(程序设计上的错误)和运行时错误(运行过程中可能出现的问题)。
2.1 逻辑错误类
逻辑错误类主要用于指示程序设计中违反预期条件的错误,这些错误通常可以在编译前或运行前检查出来。常见的逻辑错误类包括:
- std::logic_error:所有逻辑错误的基类。
- std::invalid_argument:无效参数错误。例如,当传入函数的参数不符合要求时。
- std::domain_error:参数超出函数定义域时抛出。
- std::length_error:长度错误,如试图创建超出容器限制的对象。
- std::out_of_range:当索引超出范围时抛出异常。
示例:
#include <iostream>
#include <stdexcept>
void validateAge(int age) {
if (age < 0 || age > 150) {
throw std::out_of_range("年龄超出合理范围");
}
}
int main() {
try {
validateAge(200);
} catch (const std::exception& ex) {
std::cerr << "逻辑错误捕获: " << ex.what() << std::endl;
}
return 0;
}
2.2 运行时错误类
运行时错误类用于指示在程序运行过程中出现的问题,这类错误通常不能通过编译期检查发现。常见的运行时错误类包括:
- std::runtime_error:所有运行时错误的基类。
- std::range_error:超出范围错误,通常用于数学计算中。
- std::overflow_error:上溢错误。
- std::underflow_error:下溢错误。
示例:
#include <iostream>
#include <stdexcept>
double divide(double a, double b) {
if (b == 0) {
throw std::runtime_error("除数不能为零");
}
return a / b;
}
int main() {
try {
std::cout << "结果: " << divide(10, 0) << std::endl;
} catch (const std::exception& ex) {
std::cerr << "运行时错误捕获: " << ex.what() << std::endl;
}
return 0;
}
3. 使用 <stdexcept>
抛出异常
在遇到不符合预期的情况时,使用 <stdexcept>
中的异常类可以让异常信息更具体,便于定位问题。例如:
#include <stdexcept>
#include <string>
void setName(const std::string& name) {
if (name.empty()) {
throw std::invalid_argument("名称不能为空");
}
// 继续设置名称的操作……
}
4. 捕获和处理标准异常
在捕获异常时,推荐使用基类引用捕获(如 const std::exception&
),这样可以捕获所有标准异常,且避免对象切片问题:
#include <iostream>
#include <stdexcept>
int main() {
try {
// 可能抛出 std::invalid_argument 或其他 std::logic_error 派生类的代码
setName("");
} catch (const std::exception& ex) {
std::cerr << "异常: " << ex.what() << std::endl;
}
return 0;
}
5. 自定义异常与 <stdexcept>
的关系
当标准异常类不能满足具体需求时,你可以继承自 std::logic_error
或 std::runtime_error
来定义自定义异常。这样可以利用标准异常的基本接口(如 what()
)和继承体系,同时加入自定义的错误信息。
示例:
#include <iostream>
#include <stdexcept>
#include <string>
class MyCustomException : public std::runtime_error {
public:
explicit MyCustomException(const std::string& msg)
: std::runtime_error("MyCustomException: " + msg) { }
};
void process(int value) {
if (value < 0) {
throw MyCustomException("负值不允许");
}
// 其他处理……
}
int main() {
try {
process(-1);
} catch (const std::exception& ex) {
std::cerr << "捕获自定义异常: " << ex.what() << std::endl;
}
return 0;
}
6. 常见注意事项
- 异常安全性:在抛出异常前,确保已经正确释放了资源(推荐使用 RAII 技术)。
- 信息明确:选择合适的异常类型以便清楚表达错误的性质。
- 层次结构:利用标准异常类的继承结构,有助于对不同错误进行细粒度处理。
- 异常捕获顺序:当捕获多个异常时,先捕获派生类,再捕获基类,避免被基类捕获后遗漏处理更具体的错误。
7. 结论
<stdexcept>
为 C++ 程序提供了一套标准化的异常类,用于描述逻辑错误和运行时错误。通过合理使用这些异常类,可以使程序在出错时提供清晰、有意义的错误信息,并实现统一的错误处理策略。掌握 <stdexcept>
的使用对于编写健壮、易于维护的 C++ 应用程序至关重要。
推荐阅读:
发表回复