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 类派生而来的。常用的几个异常类如图所示。
image
image

标准异常类定义

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

可以通过继承基类exception定义新的异常类

posted @ 2021-10-21 22:56  xfw121  阅读(284)  评论(0)    收藏  举报