代码中的异常与错误的区别,异常是可预见的,错误是不可预见的。C++内置了异常处理语法 元素try...catch...
- try 语句处理正常代码逻辑
- catch语句处理异常情况
- try 语句中的异常由对应的catch语句处理
try
{
double r = divide(1, 0);
}
catch(...)
{
cout << "Divided by zero..." << endl;
}
C++中通过throw语句跑出异常信息,下边来定义一个除法函数,除数为0时抛出异常
#include <iostream>
#include <string>
using namespace std;
int divide(double a, double b)
{
const double delate = 0.0000000001;
double ret = 0.0;
if ( !(-delate < b)&&(b<delate))
{
ret = a/b;
}
else
{
throw 0; //产生除0异常,异常返回
}
return ret;
}
int main()
{
try
{
divide(12, 0); //此处会抛出异常
}
catch (...)
{
cout << "Divided by zreo..." << endl;
}
system("pause");
return 0;
}
编译执行:
throw抛出的异常必须被catch处理
- 当前函数能够处理异常,程序继续往下执行
- 当前程序无法处理异常,则函数停止执行,并返回异常
- 未被处理的异常会顺着函数调用栈向上传播,直到被处理为止, 否则程序将停止执行
对于上边的代码,假如我们在main函数中不使用try...catch...,直接调用divide(12, 0),即不对函数抛出的异常做处理,那么程序执行时会崩溃。如下:
C++中的异常处理,同一个try语句可以 跟上多个catch语句
- try语句中可以抛出任何类型的异常(如int 、char*、string等)
- catch语句可以定义具体处理的异常类型
- 不同类型的异常由不同的catch语句负责处理
- catch(...)用于处理所有类型的异常
- 任何异常都只能被捕获(catch)一次
异常处理的匹配规则
- 异常抛出后,至上而下严格匹配每一个catch语句处理的类型
- 异常处理匹配时,不进行任何的类型转换
try
{
throw 1;
}
catch (Type1 t1) //先匹配Type1
{
}
catch (Type2 t2) //Type1匹配失败则匹配Type2
{
}
catch (TypeN tN) //Type2匹配失败则匹配TypeN
{
}
catch(...) //如果都匹配失败则匹配...
{
}
下边以具体代码展示一下:
#include <iostream>
#include <string>
using namespace std;
void demo()
{
try
{
throw 12.03; //抛出一个double类型的异常
}
catch (int t)
{
cout << "catch (int t)" << endl;
}
catch (double t)
{
cout << "catch (double t)" << endl;
}
catch (char* t)
{
cout << "catch (char* t)" << endl;
}
catch(...)
{
cout << "catch(...)" << endl;
}
}
int main()
{
demo();
system("pause");
return 0;
}
编译输出:
从输出看到,由于我们抛出的异常是double类型,所以会严格匹配catch(double t)语句块去处理抛出的异常。这也符合了我们所说的异常处理是至上而下严格匹配catch语句块的,不做任何的类型转换。
总结:
- try...catch...是C++中异常处理的专用语句
- try语句处理正常代码逻辑,catch语句处理异常情况
- 同一个 try语句可以跟上多个catch语句
- 异常处理必须严格匹配, 不进行任何的类型转换