《C++11标准库》4.3.1标准的 Exception Class(异常类)

所有被语言本身或标准库抛出的异常,都派生自基类 exception ,定义于 <exception> 。它是若干标准异常的基类,它们共同形成一个类体系,如图所示,

这些标准异常可被分为三组:

1:语言本身支持的异常。

2:C++标准库发出的异常。

3:程序作用域之外发出的异常。

逻辑错误通常可以避免,因为其错误发生在作用域内,例如先决条件被违反。运行期异常则是由一个位于程序作用域之外的原因触发,例如资源不足。

针对语言支持而设计的异常类:

此类异常用以支撑某些语言特性,所以,从某种角度说他们不是标准库的一部分,而是核心语言的一部分。例如以下操作如果失败就会抛出异常:

*运行期间,当一个 reference(引用)身上的“动态类型转换”失败时,dynamic_cast 会抛出 bad_cast 异常,此异常定义于 <typeinfo>。

*运行期类型辨识(RTTI)过程中,如果交给 typeid 操作符的实参为 0或为空指针,typeid 操作符会抛出 bad_typeid 异常,此异常定义于<typeinfo>.

*定义于<exception> 内的bad_exception 异常用来处理非预期的异常。它可以由函数 unexpected() 抛出,该函数会在“某个函数抛出的异常不在异常明细内”时被调用。然而请注意,自C++11起,已经不再提倡使用异常明细。

这些异常也可以被程序库函数抛出。例如:bad_cast 有可能由 use_facet<>抛出,如果一个facet 在某个 local 内不可用的话。

针对逻辑差错而设计的类。

针对逻辑差错而设计的异常总是派生自 logic_error 。所谓逻辑差错就是可在程序中避免的错误,例如通过“对函数实参进行额外测试”而避免出现逻辑差错。这类错误包含如“违背逻辑先决条件”或“违反 class不变性”等。C++标准库提供了以下五种针对逻辑差错的异常类:

*invalid_argument 表示无效实参,例如将 bitset(array of bits)以char 而非‘0’或‘1’进行初始化。

*length_error 指出某个行为“可能超越最大容许大小”,例如在类似 array 的集合或字符串(string)中采用一个错误索引。

*domain_error 指出领域范畴内的错误。

*自C++11起,future_error 用来指出当使用非同步系统调用时发生的逻辑差错。此范围内的运行期差错乃是借由 class system_error。

一般而言,针对逻辑差错而设计的异常类往往被定义于<stdexcept>内,不过 class future_error却是被定义于<future>。

针对运行期差错而设计的异常类

派生自 runtime_error 的异常都被用来指出“不在程序作用域内且不容易回避”的事件。

C++标准库为此提供了以下几个class:

*range_error 指出内部计算时发生的区间错误。自C++11起,C++标准库有可能在“wide sring 和 byte string之间转换”时发生这个异常。

*underflow_error指出算数运算发生上溢。C++标准库中,如果一个 bitset 被转换为一个整数值,就会抛出这个异常。

*underflow_error指出算数运算发生下溢。

*自C++11起,system_error用来指出因底层操作系统而发生的差错。C++标准库有可能在并发环境中抛出异常。例如:class thread ,用以控制data race 的那些类以及 async() 。

*只要全局操作符 new 失败,定义于<new>的bad_alloc就会抛出异常,除非用的时new的 nothrow版本。由于这个异常可能于任何时间在任何较复杂的程序中发生,所以可认为是一个最重要的异常。

自C++11起,派生自bad_alloc的bad_array_new_length会被new抛出——如果传给new的大小小于0或超过编译器定义的极限(也就是说,那就是个逻辑问题而不是一个运行时期错误)。

*当“根据一个shared pointer创建一个weak pointer”的操作失败,定于于<memory>中的bad_weak_ptr会被抛出。

*当一个function 外覆物被调用但其实际没有目标时,定义于<functional>中的bad_function_call会被抛出。

此外,针对标准库中的 I/O部分,有一个特别的异常类 ios_base::failure被定义于<ios>。此类异常可能会在 stream 由于发生错误或遇上 end-of-file 而改变其状态时被抛出。自C++11起这个类派生自 system_error,在C++11之前它直接派生自 exception。

从概念上来说,bad_alloc可被视为属于一种 system error。然而由于历史原因,也由于其重要性,当编译器想要表达“内存不足“时,多半会抛出 bad_alloc而不是system_error。

一般而言,针对运行期差错而设计的class被定义于<stdexcept>内。但system_error却被定义于<system_error>内。

由标准库抛出的异常

如上所述,几乎所有的异常类都有可能被C++标准库抛出。尤其是,无论何时分配储存空间,都有可能抛出 bad_alloc异常。

此外,由于标准库可能用到引用程序开发人员所写代码,所以也可以间接掷出任何异常。

标准库的任何具体实现都有坑能提供更多异常类(或为兄弟类或派生为子类)。然而使用这些非标准类将导致程序难以移植,因为一旦你想采用其它标准库实现,就不得不修改程序。所以,最好只使用标准异常类。

异常类的头文件

异常类定义于许多头文件中。为了能够处理标准库可能抛出的异常,必须包含:

#include<exception>
#include<stdexcept>
#include<system_error>
#include<new>
#include<ios>
#include<future>
#include<typeinfo>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值