程序出错
程序的错误大致可以分为三种,分别是语法错误、逻辑错误和运行时错误
说明 | |
---|---|
语法错误 | 语法错误在编译和链接阶段就能发现,只有 100% 符合语法规则的代码才能生成可执行程序。语法错误是最容易发现、最容易定位、最容易排除的错误。 |
逻辑错误 | 逻辑错误是说我们编写的代码思路有问题,不能够达到最终的目标,这种错误可以通过调试来解决。 |
运行时错误 | 运行时错误是指程序在运行期间发生的错误,例如除数为 0、内存分配失败、数组越界、文件不存在等。C++ 异常(Exception)机制就是为解决运行时错误而引入的。 |
C++ 异常(Exception)机制
捕获异常的语法为:
try{
// 可能抛出异常的语句
}catch(exceptionType variable){
// 处理异常的语句
}
try
和catch
都是 C++ 中的关键字,后跟语句块,不能省略{ }
。try
中包含可能会抛出异常的语句,一旦有异常抛出就会被后面的 catch 捕获。try
只是“检测”语句块有没有异常,如果没有发生异常,它就“检测”不到。catch 是“抓住”的意思,用来捕获并处理 try 检测到的异常;如果 try 语句块没有检测到异常(没有异常抛出),那么就不会执行 catch 中的语句。catch
关键字后面的exceptionType variable
指明了当前 catch 可以处理的异常类型,以及具体的出错信息。catch能匹配成功所有的数据类型的异常对象,包括C++语言提供所有的原生数据类型的异常对象,如int、double;还有char 、int 这样的指针类型,另外还有数组类型的异常对象;同时也包括所有自定义的抽象数据类型。例1
#include <iostream> #include <exception> using namespace std; void main () { try { throw 1; throw "error"; } catch(char *str) { cout << str << endl; } catch(int i) { cout << i << endl; } }
例2
#include < iostream> #include < exception > using namespace std; //自己定义Exception class myexception: public exception { ... }myex; void main () { try { if(true) //如果,则抛出异常; throw myex; } catch (myexception& e) { cout << e.what() << endl; } }
try 检测到异常后程序的执行流会发生跳转,从异常点跳转到 catch 所在的位置,位于异常点之后的、并且在当前 try 块内的语句就都不会再执行了;即使 catch 语句成功地处理了错误,程序的执行流也不会再回退到异常点。
异常可以发生在当前的 try 块中;也可以发生在 try 块所调用的某个函数中;或者是所调用的函数又调用了另外的一个函数,这个另外的函数中发生了异常。这些异常,都可以被 try 检测到。
标准C++异常类
标准异常都派生自一个公共的基类exception。
C++有很多的标准异常类:
exception派生
class logic_error; //逻辑错误,在程序运行前可以检测出
class runtime_error; //运行时错误,仅在程序运行中检测
class bad_alloc; //存储分配错误
class bad_cast; //在运行时类型识别中有一个无效的dynamic_cast表达式
class bad_typeid; //报告在表达试typeid(*p)中有一个空指针p
logic_error派生
class domain_error; //违反了前置条件
class invalid_argument; //指出函数的一个无效参数
class length_error; //指出有一个超过类型size_t的最大可表现值长度的对象的企图
class out_of_range; //参数越界
runtime_error派生
class range_error; //违反后置条件
class overflow_error; //报告一个算术溢出
标准库异常类定义在以下四个头文件中
- exception头文件:定义了最常见的标准异常类,其类名为exception。只通知异常的产生,但不会提供更多的信息
- stdexcept头文件
- new头文件定义了bad_alloc异常类型,提供因无法分配内存而由new抛出的异常
- typeinfo头文件定义了bad_cast异常类型
PS:网上很多帖子上的异常类层次结构不同,本文中的层次结构是MSDN中一一查询所得。