异常处理

程序在运行过程中往往遇到运行阶段错误,这些不可预见或者可以预见的错误都会导致程序无法正常继续运行。在遇到异常时,一般有以下几种处理方法。

调用abort()

abort()位于cstdlib头文件中,调用abort()可以向cerr发送程序异常终止的消息,并结束程序运行。

使用异常

使用异常类对错误进行处理,一般由throw关键字抛出,并使用try ... catch ...语句块进行捕获和处理。try/catch的使用格式为:

try {
    // 可能会出现异常的语句块
} catch (要相应的异常类型 捕获异常变量) {
    // 异常处理语句块
}

C++中提供了exception类,但是使用throw进行抛出的时候,并不一定必须抛出exception或者其子类的实例,也可以直接抛出一个字符串,并使用char*来进行捕获,还可以是一个自定义的类。

throw关键字还可以跟在函数声明后面,列举函数可能会抛出的异常类型,使用格式示例如下:

void may_be_errors(double z) throw(const char*, exception);

函数可以抛出的多种异常类在throw后的括号中使用逗号分隔列出,在实现函数定义时,也需要将函数声明中的异常声明也包含进来。如果throw的列表是空白的,说明这个函数不会抛出任何异常。在 C++11 中可以使用关键字noexcept来标记函数不可以抛出任何异常,大致相当于之前的throw(),但编译器的处理方式有所区别。

C++库定义了多种异常,在头文件<exception>中定义了exception类,可以作为其他异常类的基类。exception类中有一个what()虚成员函数,用来返回一个字符串,在继承实现异常时需要重载。头文件<stdexcept>中还定义了其他的几个异常类,都是从exception类中派生来的,其常用的几个类如下。

  • runtime_error,运行时错误;
  • range_error,超出值域;
  • overflow_error,计算上溢出;
  • underflow_error,计算下溢出;
  • logic_error,逻辑错误;
  • domain_error,定义域错误;
  • invalid_argument,无效参数;
  • length_error,长度错误;
  • out_of_bounds,超出范围。