异常处理
基础用法
- throw表达式
throw runtime_error("xxxxx");
其中,runtime_error
是标准库异常类型的一种,定义在stdexcept.h。 - try block
try
{
program-statements
}
catch(exception-declaration)
{
hadler-statements
}
catch(exception-declaration)
{
hadler-statements
}
...
示例
try {...}
catch (runtime_error err)
{
cout<<err.what()<<endl;
}
每个标准库异常类都定义了一个名为what的成员函数,这些函数没有参数, 返回值是C风格字符串(const char *
)
3. 标准异常
C++
标准库定义了一组类,用于报告标准库函数遇到的问题,也可用于用户程序。
- exception 头文件:定义了通用的异常类 exception,只报告异常发生,不提供任何额外信息。
- stdexcept 头文件:定义了几种常用的异常类。
- new 头文件:定义了
bad_alloc
异常类型 type_info
定义了bad_cast
异常类型。
exception 、bad_alloc
、bad_cast
只能以默认初始化形式初始化,不允许提供初始化值。
其他异常类型行为相反,使用string或C风格字符串初始化,不允许默认初始化。
标准库异常类型
拓展知识
在C++
中通过throwing来raised一个异常。
被抛出的表达式的类型以及当前的调用链共同决定了哪段代码(handler)将被用来处理该异常。
被选中的handler是在调用链中与抛出对象类型匹配的最近的处理代码。
- 当执行一个throw时,跟在throw后面的语句将不再被执行。相反,程序的控制权从throw转到与之匹配的catch模块。该catch可能是局部catch,也可能位于直接或间接调用了发生异常的函数的另一个函数中。
- 控制权的转移有两个重要含义:
- 沿着调用链的函数可能会提前退出
- 一旦程序开始执行异常处理代码,则沿着调用链创建的对象将被销毁。
由于throw后面跟着的语句将不再被执行,所以throw的用法类似于return:通常作为条件语句的一部分或者作为某个函数的最后/唯一一条语句。
栈展开
当throw出现在try block内时,检查与该try block关联的catch子句。如果找到了匹配的catch,就用该catch处理异常。如果没有,且该try嵌套在其他try内,则继续检查外层try…
上述过程:栈展开stack unwinding
当最终找不到匹配的catch时,程序将调用标准库函数terminate。
如果一个异常没有被捕获,它将终止当前程序。