1、当抛出一个异常后,程序会暂定当前函数的执行过程并以栈展开的方式寻找与异常匹配的catch字句,若找不到catch,程序将调用标准库函数terminate,终止程序的执行。
2、栈展开过程中编译器会确保退出块中已创建的对象能被正确地销毁,如果对象是类类型的话,它的析构将被调用。
3、析构中不应该抛出异常
在栈展开过程中运行类类型局部对象的析构函数(可以看出析构函数成了异常处理的一部分),因为这些析构函数是自动执行的,所以它们不应该抛出异常(这时的析构本来就是用来处理异常的,它再抛出异常的话,那由谁来处理呢?,所以不应该),否则程序会异常终止。在实际开发中,尤其是在大型程序中,很难保证析构中不会发生异常,正确的做法是将析构中发生的异常封装在它内部,在析构内部解决,这样析构就不会对外抛出异常了
4、catch匹配
一般认为除了以下几个规则,其他的包括标准算术类型转换和类类型转换在内的所有转换规则都不能在匹配catch的过程中使用
- 允许从非常量向常量的类型转换
- 允许从派生类向基类的类型转换
- 允许数组被转换成指向数组类型的指针,允许函数被转换成指向该函数类型的指针
5、重新抛出
重新抛出是只有一个throw,不包含任何表达式的语句,即空的throw语句,空throw语句只能出现在catch语句或catch语句直接或间接调用的函数内,其他地方 编译器将直接调用terminate
6、using指示与using声明
using指示:using namespace namespacename;
using声明:using namespacename::member;
namespace blip{
int i = 16, j = 15, k = 23;
}
int j = 0;
void manip()
{
using namespace blip;
++i; //将blip::i设定为17
++j; //错误:全局的j还是blip::j?
++::j; //正确:将全局的j设定为1
++blip::j; //正确:将blip;:j设定为16
int k = 97; //局部的k隐藏了blip::k,因为
//using指示就好像在manip之前的
//全局作用域定义了内容
++k; //这个k是98
++blip::k; //局部定义过后就得用原本的方
//式来操作blip的k,这里k为24
}