C++异常处理机制
参考优秀文章
| C++异常处理入门,C++ try catch入门 | http://c.biancheng.net/view/2330.html |
|---|---|
为什么需要异常处理机制?
程序的错误大致可以分为三种,分别是语法错误、逻辑错误和运行时错误:
- 语法错误
语法错误在编译和链接阶段就能发现,只有 100% 符合语法规则的代码才能生成可执行程序。语法错误是最容易发现、最容易定位、最容易排除的错误,程序员最不需要担心的就是这种错误。 - 逻辑错误
逻辑错误是说我们编写的代码思路有问题,不能够达到最终的目标,这种错误可以通过调试来解决。 - 运行时错误
运行时错误是指程序在运行期间发生的错误,例如除数为 0、内存分配失败、数组越界、文件不存在等。C++ 异常(Exception)机制就是为解决运行时错误而引入的。
程序运行时常会碰到一些异常情况,例如:
- 做除法的时候除数为 0;
- 用户输入年龄时输入了一个负数;
- 用 new 运算符动态分配空间时,空间不够导致无法分配;
- 访问数组元素时,下标越界;打开文件读取时,文件不存在。
注意!!!这些异常
如果不进行处理,程序会崩溃,直接退出。
常见的异常操作
- 可以是给出错误提示信息,然后让程序沿一条不会出错的路径继续执行;
- 也可能是不得不结束程序,但在结束前做一些必要的工作,如将内存中的数据写入文件、关闭打开的文件、释放动态分配的内存空间等。
c++引用异常处理机制
与传统处理机制相比
-
一个库的作者可以检测出发生了运行时错误,但一般不知道怎样去处理它们(因为和用户具体的应用有关);另一方面,库的用户知道怎样处理这些错误,但却无法检查它们何时发生(如果能检测,就可以在用户的代码里处理了,不用留给库去发现)。让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。
-
不在函数发生异常处,立即处理异常,而是抛出异常,交给函数调用者处理,方便异常进行集中处理,程序更容易编写和维护。
基本机制思想
- 函数A在执行过程中发现异常时可以不加处理,而只是“拋出一个异常”给A的调用者,假定为函数B。A拋出异常而不加处理会导致函数A立即中止,在这种情况下,函数B可以选择捕获A拋出的异常进行处理,也可以选择置之不理。如果置之不理,这个异常就会被拋给B的调用者,以此类推。
- 如果一层层的函数都不处理异常,异常最终会被拋给最外层的 main 函数。main 函数应该处理异常。如果main函数也不处理异常,那么程序就会立即异常地终止。
C++异常处理基本语法
throw(抛出异常)
抛出一个异常对象(对象类型可以是基本类型,也可以是类)
try...catch (捕获异常)
执行过程
- 执行 try 块中的语句,如果执行的过程中没有异常拋出,那么执行完后就执行最后一个 catch 块后面的语句,所有 catch 块中的语句都不会被执行;
- 如果 try 块执行的过程中拋出了异常,那么拋出异常后立即跳转到第一个“异常类型”和拋出的异常类型匹配的 catch 块中执行(称作异常被该 catch 块“捕获”),执行完后再跳转到最后一个 catch 块后面继续执行。
一些特性 - catch(...)可捕捉任意异常类型对象
- 函数的异常声明列表
为了增强程序的可读性和可维护性,使程序员在使用一个函数时就能看出这个函数可能会拋出哪些异常,C++ 允许在函数声明和定义时,加上它所能拋出的异常的列表,具体写法如下:
![image]()
![image]()
C++标准异常类
C++ 标准库中有一些类代表异常,这些类都是从 exception 类派生而来的。常用的几个异常类如图所示。


标准异常类定义
std::exception:
标准异常类的基类,其类的声明在头文件
std::exception类定义
std::exception类定义了无参构造函数、拷贝构造函数、拷贝赋值运算符、一个虚析构函数和一个名为what的无参虚成员。其中what函数返回一个const char*,该指针指向一个以null结尾的字符数组,并且确保不会抛出任何异常,该字符串的目的是提供关于异常的一些文本信息。除析构函数外,其它函数均通过关键字noexcept说明此函数不会抛出异常。



浙公网安备 33010602011771号