异常
1)try、throw和catch关键字
- 在程序中的用法如下
#include <iostream>
using namespace std;
int main()
{
double m = 1, n = 0;
try {
cout << "before dividing." << endl;
if (n == 0)
throw - 1; //抛出int型异常
else if (m == 0)
throw - 1.0; //拋出 double 型异常
else
cout << m / n << endl;
cout << "after dividing." << endl;
}
catch (double d) {
cout << "catch (double)" << d << endl;
}
catch (...) {
cout << "catch (...)" << endl;
}
cout << "finished" << endl;
return 0;
}
//运行结果
//before dividing.
//catch (...)
//finished
- 程序的执行流程是先执行try包裹的语句块,如果执行过程中没有异常发生,则不会进入任何catch包裹的语句块
- 如果发生异常,则使用throw进行异常抛出,再由catch进行捕获
- throw可以抛出各种数据类型的信息,代码中使用的是数字,也可以自定义异常class
- 可以使用catch(...)的方式捕获任何异常(不推荐)
- 如果catch了异常,当前函数如果不进行处理,或者已经处理了想通知上一层的调用者,可以在catch里面再throw异常。
2)函数的异常声明列表
- 程序员在定义函数的时候知道函数可能发生的异常,可以在函数声明和定义时,指出所能抛出异常的列表
int fun() throw(int,double,A,B,C){...};
- 表名函数可能会抛出int,double型或者A、B、C三种类型的异常
3)C++标准异常类 exception
- C++ 标准库中有一些类代表异常,这些类都是从 exception 类派生而来
- bad_typeid:使用typeid运算符,如果其操作数是一个多态类的指针,而该指针的值为 NULL,则会拋出此异常
- bad_cast:在用 dynamic_cast 进行从多态基类对象(或引用)到派生类的引用的强制类型转换时,如果转换是不安全的,则会拋出此异常
- bad_alloc:用 new 运算符进行动态内存分配时,如果没有足够的内存,则会引发此异常
- out_of_range:用 vector 或 string的at 成员函数根据下标访问元素时,如果下标越界,则会拋出此异常
typeid
- 在揭开typeid之前,需先了解RTTI(Run-Time Type Identification,运行时类型识别)
- 它使程序能够获取由基指针或引用所指向的对象的实际派生类型
- 允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。
- 在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和typeid
- dynamic_cast允许运行时刻进行类型转换,从而使程序能够在一个类层次结构中安全地转化类型
- 相对应的还有一个非安全的转换操作符static_cast
- typeid操作符的返回结果是名为type_info的标准库类型的对象的引用
- typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用