异常
- 异常是一种程序控制机制,与函数机制独立和互补 函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它依附于栈结构,却可以同时设置多个异常类型作为网捕条件,从而以类型匹配在栈机制中跳跃回馈.
- 异常设计目的 栈机制是一种高度节律性控制机制,面向对象编程却要求对象之间有方向、有目的的控制传动,从一开始,异常就是冲着改变程序控制结构,以适应面向对象程序更有效地工作这个主题,而不是仅为了进行错误处理。
# 1 异常的基本语法
# 1.1 抛掷异常的程序段
void Func(){
...
throw 表达式;
...
}
# 1.2 捕获并处理异常的程序段
try{
复合语句
}
catch(异常类型声明){
}
catch(异常类型声明){
}
1) 若有异常则通过throw操作创建一个异常对象并抛掷。 2) 将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。 3) 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后跟随的最后一个catch子句后面的语句继续执行下去。 4) catch子句按其在try块后出现的顺序被检查。匹配的catch子句将捕获并处理异常(或继续抛掷异常)。 5) 如果匹配的处理器未找到,则运行函数terminate将被自动调用,其缺省功能是调用abort终止程序。 6) 处理不了的异常,可以在catch的最后一个分支,使用throw语法,向上扔。
#include <iostream>
using namespace std;
int divide(int x, int y)
{
if (y == 0)
{
throw x;
}
return x/y;
}
int main(void)
{
try
{
cout << "8/2 = " << divide(8, 2) << endl;
cout << "10/0 = " << divide(10, 0) << endl;
}
catch(int e)
{
cout << "e" << " is divided by zero!" << endl;
}
catch(...)
{
cout << "未知异常" << endl;
}
return 0;
}
# 2 栈解旋
异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。
#include <iostream>
using namespace std;
class MyException {};
class Test
{
public:
Test(int a=0, int b=0)
{
this->a = a;
this->b = b;
cout << "Test 构造函数执⾏" << "a:" << a << " b: " << b << endl;
}
void printT()
{
cout << "a:" << a << " b: " << b << endl;
}
~Test()
{
cout << "Test 析构函数执⾏" << "a:" << a << " b: " << b << endl;
}
private:
int a;
int b;
};
void myFunc() throw (MyException)
{
Test t1;
Test t2;
cout << "定义了两个栈变量,异常抛出后测试栈变量的如何被析构" << endl;
throw MyException();
}
int main(void)
{
//异常被抛出后,从进⼊try块起,到异常被抛掷前,这期间在栈上的构造的所有对象>,
//都会被⾃动析构。析构的顺序与构造的顺序相反。
//这⼀过程称为栈的解旋(unwinding)
try
{
myFunc();
}
catch(MyException &e)
//catch(MyException ) //这⾥不能访问异常对象
{
cout << "接收到MyException类型异常" << endl;
}
catch(...)
{
cout << "未知类型异常" << endl;
}
return 0;
}
/*
Test 构造函数执⾏a:0 b: 0
Test 构造函数执⾏a:0 b: 0
定义了两个栈变量,异常抛出后测试栈变量的如何被析构
Test 析构函数执⾏a:0 b: 0
Test 析构函数执⾏a:0 b: 0
接收到MyException类型异常
*/