try
{
// 保护的标识代码
}catch( ExceptionName e1 )
{
// catch 块
}catch( ExceptionName e2 )
{
// catch 块
}catch( ExceptionName eN )
{
// catch 块
}
异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。
被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成
一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。(这里的处理类似于函数的传值返回)
catch(…)可以捕获任意类型的异常,问题是不知道异常错误是什么。
实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获,这个在实际中非常实用,我们后面会详细讲解这个。
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#include
double devision(int a,int b)
{
if (b == 0)
throw "Division by zero condition!";
else
return (double)a / (double)b;
}
void Func()
{
int x, y;
cin >> x >> y;
cout << devision(x, y) << endl;
}
int main()
{
try {
Func();
}
//catch (const char* errmgs)
//{
// cout << errmgs << endl;
//}
catch (...)
{
cout << "捕获未知异常!" << endl;
}
return 0;
}
上述代码中,我们定义:当被除数b为0时为异常事件,进行捕获,在main函数里进行调用,如果有匹配的catch 系统就会优先捕获,
//catch (const char* errmgs)
//{
// cout << errmgs << endl;
//}
当我们定义好匹配的catch时,系统会直接调用匹配选项捕获异常,从而跳过下面的异常处理。
情况4
在前面try 当输入a=0时抛出1111;这里,当第一个异常没出现会接着往下运行,但是遵守就近原则,一出现就抛出!
try
{
int len, time;
//cin >> len >> time;
len = rand();
time = rand() % 5;
cout << devision(len, time) << endl;
}
catch (...)
{
// 释放
cout << __LINE__ << " delete []" << array << endl;
delete[] array;
throw; // 捕获什么抛什么
}
cout << __LINE__ << " delete []" << array << endl;
delete[] array;
C++异常的优点:
// 1.下面这段伪代码我们可以看到ConnnectSql中出错了,先返回给ServerStart,ServerStart再
返回给main函数,main函数再针对问题处理具体的错误。
// 2.如果是异常体系,不管是ConnnectSql还是ServerStart及调用函数出错,都不用检查,因为抛
出的异常异常会直接跳到main函数中catch捕获的地方,main函数直接处理错误。
int ConnnectSql()
{
// 用户名密码错误
if (...)
return 1;
// 权限不足
if (...)
return 2;
}
int ServerStart() {
if (int ret = ConnnectSql() < 0)
return ret;
int fd = socket()
if(fd < 0)
return errno;
}
int main()
{
if(ServerStart()<0)
...
return 0;
}
异常总体而言,利大于弊,所以工程中我们还是鼓励使用异常的。另外OO的语言基本都是用异常处理
错误,这也可以看出这是大势所趋