什么是异常?
(1)异常是一种程序控制机制,与函数机制独立和互补。
函数是一种以栈结构展开的上下函数衔接的程序控制系统;而异常是另一种控制结构,它依附于栈结构,却可以同时设置多 个异常类型作为网捕条件,从而以类型匹配在栈机制中跳跃回馈。
异常的设计目的?
(1)栈机制是一种高度节律性控制机制,面向对象编程却要求对象之间有方向、有目的的控制传动。
从一开始,异常就是冲着改变程序控制结构,以适应面向对象程序更有效地工作这个主题,而不是仅为了进行错误处理。
异常设计出来之后,却发现在错误处理方面获得了最大的好处。
异常的基本语法?
抛掷异常的程序段: | 捕获并处理异常的程序段:
void fun() | try
{ | {
......... | 复合语句
throw 表达式; | }
......... | catch(异常类型声明)
} | {复合语句}
| catch(类型 (形参) )
| {复合语句}
| ..........
异常处理思想?
(1)C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以在适当的位置设计对不同类型异常的处理。
(2)异常是专门针对抽象编程中的一系列错误处理的。C++中不能借助函数机制,因为栈结构的本质是先进后出,依次访问,无法进行跳跃,但错误处理的特征却是遇到错误信息就想要转到若干级之上进行重新尝试。
(3)异常超脱于函数机制,决定了其对函数的跨越式回跳。
(4)异常跨越函数。
异常的接口声明:
(1)为了加强程序的可读性,可以在函数声明中列出可能抛出的所有异常类型。
int Div(int x,int y) throw(int,char); //可以抛出int、char类型异常
(2)如果在函数声明中没有包含异常接口声明,则次函数可以抛掷任何类型的异常
int Div(int x,int y); //可以抛出任何类型异常
(3)一个不抛掷任何类型异常的函数可以声明为:
int Div(int x,int y) throw(); //不可以抛出异常
(4) 如果一个函数抛出了它的异常接口声明所不允许抛出的异常,unexpected函数会被调用,该函数默认行为调用terminate函数中止程序。
异常的层次结构:
举例:
设计一个数组类MyArray,重载[ ]操作。
数组初始化,对数组的个数进行有效检查:
1、index<0,抛出异常eNegative
2、index=0,抛出异常eZero
3、index>1000,抛出异常eTooBig
4、index<10,抛出异常eTooSmall
5、eSize类是以上类的父类,实现有参构造函数,并定义virtual void printErr() 输出错误。
#include<iostream>
using namespace std;
class MyArray
{
private:
int m_len;
int *m_data;
public:
MyArray(int l);
~MyArray();
int &operator [](int index) //对[]进行重载
{
return m_data[index];
}
int Getlength()
{
return m_len;
}
class eSize //父类
{
protected:
const char *ErrMsg;
public:
eSize(char *msg) : ErrMsg(msg)
{
}
virtual void printErr() = 0; //虚函数
};
class eNegative : public eSize
{
public:
eNegative() : eSize("Negative Exception")
{
}
void printErr()
{
cout<< ErrMsg <<endl;
}
};
class eZero : public eSize
{
public:
eZero() : eSize("Zero Exception")
{
}
void printErr()
{
cout<< ErrMsg <<endl;
}
};
class eTooSmall : public eSize
{
public:
eTooSmall() : eSize("TooSmall Exception")
{
}
void printErr()
{
cout<< ErrMsg <<endl;
}
};
class eTooBig : public eSize
{
public:
eTooBig() : eSize("TooBig Exception")
{
}
void printErr()
{
cout<< ErrMsg <<endl;
}
};
};
MyArray::MyArray(int l)
{
m_len = l;
if(m_len < 0)
{
throw eNegative(); //抛出异常
}
else if(m_len == 0)
{
throw eZero();
}
else if(m_len > 0 && m_len <= 10)
{
throw eTooSmall();
}
else if(m_len > 1000)
{
throw eTooBig();
}
m_data = new int[m_len];
}
MyArray::~MyArray() //析构函数
{
if(m_data != NULL)
{
delete[] m_data;
}
}
int main()
{
try
{
MyArray a(1); //改变数值 可以输出不同的结果
for(int i=0; i<a.Getlength(); i++)
{
a[i] = i;
}
}
catch (MyArray::eNegative &e) //异常捕捉处理
{
e.printErr();
}
catch (MyArray::eZero &e)
{
e.printErr();
}
catch (MyArray::eTooSmall &e)
{
e.printErr();
}
catch (MyArray::eTooBig &e)
{
e.printErr();
}
return 0;
}