c++++标准库异常类体系以std::exception为基类,派生出逻辑错误和运行时错误两大类及其他特殊类型。1. std::exception是所有标准异常的基类,提供虚函数what()返回错误描述字符串,通常用于捕获所有标准异常;2. std::logic_error表示可预见的逻辑错误,包含std::invalid_argument(非法参数)、std::domain_error(定义域错误)、std::length_error(长度超出限制)、std::out_of_range(访问越界)等子类,适用于输入验证场景;3. std::runtime_error处理不可预测的运行时错误,如std::range_error(范围错误)、std::overflow_error(溢出)、std::underflow_error(下溢),常用于文件操作、网络请求等场景,需传入详细错误信息;4. 其他特殊异常包括std::bad_alloc(内存分配失败)、std::bad_cast(类型转换失败)、std::bad_typeid(typeid操作错误)、std::bad_function_call(空函数调用),虽不全继承自std::exception,但现代实现仍统一处理。建议优先使用具体异常类型以提升代码可维护性。
C++标准库中定义了一套异常类,用于在程序运行过程中报告错误。这些异常类都继承自
std::exception
基类。常见的异常类型主要包括
std::runtime_error
、
std::logic_error
以及其他一些更具体的子类。
1.
std::exception
std::exception
是所有标准异常的基类
这是整个C++标准异常体系的根节点,所有其他标准异常类都是从它派生出来的。它提供了一个虚函数
what()
,返回一个描述错误信息的 C 字符串。
- 用途:通常不会直接抛出这个类的对象,而是作为捕获所有标准异常的通用方式。
- 示例用法:
try { // 可能抛异常的代码 } catch (const std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; }
2.
std::logic_error
std::logic_error
表示逻辑错误,可在运行前检测到的问题
这类异常表示程序中的逻辑错误,理论上可以在编译或调试阶段发现,比如无效参数、断言失败等。
立即学习“C++免费学习笔记(深入)”;
常见子类包括:
-
std::invalid_argument
:传递了非法参数
-
std::domain_error
:输入值不在函数定义域内
-
std::length_error
:试图创建超出最大允许长度的对象
-
std::out_of_range
:访问越界(如 vector 的 at 方法)
使用建议:
- 在函数内部验证输入时非常有用。
- 比如你在写一个解析字符串为整数的函数,遇到非数字字符就可以抛出
std::invalid_argument
。
3.
std::runtime_error
std::runtime_error
表示运行时错误,无法提前预测的问题
这类异常表示只有在运行时才能检测到的错误,例如文件读取失败、资源加载异常等。
常见子类包括:
-
std::range_error
:计算结果超出了可表示范围
-
std::overflow_error
-
std::underflow_error
- 还有 I/O 相关的异常,比如
std::ios_base::failure
(虽然不属于标准异常层次结构)
典型场景:
- 文件操作失败
- 网络请求中断
- 内存分配失败(不过这通常是
std::bad_alloc
,属于低层异常)
注意:
- 抛出
std::runtime_error
时要传入合适的错误信息字符串,便于调试和日志记录。
- 示例:
if (file.fail()) { throw std::runtime_error("Failed to open file"); }
4. 其他特殊异常类型
除了上面两大类之外,还有一些特殊的异常类用于特定情况:
-
std::bad_alloc
:当
new
分配内存失败时抛出
-
std::bad_cast
:动态类型转换失败(如
dynamic_cast
)
-
std::bad_typeid
:使用 typeid 操作符时出现错误
-
std::bad_function_call
:调用空的
std::function
对象
这些异常不是从
std::exception
派生的全部子类(比如
bad_alloc
是),但大多数现代实现仍然统一处理。
基本上就这些。标准库提供的异常类已经覆盖了大部分常见错误场景,使用时应尽量选择最贴切的类型,而不是笼统地抛
runtime_error
。这样有助于写出清晰、可维护的异常处理逻辑。
评论(已关闭)
评论已关闭