程序运行时常会碰到一些异常情况,例如:数组越界,除以0,内存分配失败等。这些情况,如果放任不管,那么就会发生错误。
C++提供了异常的捕获和处理。并且异常捕捉和异常处理可以不在一个函数之中。这能帮助我们更好的设计程序。这就是说函数 A 在执行过程中发现异常时可以不加处理,而只是“拋出一个异常”。这个异常可能会被A的调用者B来处理。函数B可以选择捕获 A 拋出的异常进行处理,也可以选择置之不理。如果置之不理,这个异常就会被拋给 B 的调用者,以此类推。如果一层层的函数都不处理异常,异常最终会被拋给最外层的 main 函数。main函数应该处理异常。如果main函数也不处理异常,那么程序就会立即异常地中止。
异常的语言如下:
throw 表达式; //在产生异常的地方,抛出异常
try
{
//TODO:调用函数或者是一些语句。
}
catch(异常类型1) //捕捉的异常类型
{
//处理异常
}
...
catch(异常类型n)
{
//处理异常
}
总结来说就是C++通过throw来抛出异常,通过try...catch来捕获处理异常。下面是一个例子。
#include<iostream>
using std::endl;
using std::cout;
double div(double x, double y)
{
if (0 == y)
{
throw y; //抛出一个double类型的异常
}
return x / y;
}
int main()
{
try
{
div(3.3, 1.1); //不会抛出异常
div(23.23, 0.0); //会抛出异常。
}
catch (double e)
{
cout << "除数为" << e << endl;
}
catch (...)
{
cout << "其它未知异常" << endl;
}
return 0;
}
其中catch(...)表示捕捉任意类型的异常。
抛出异常以后,当前函数将不再往下执行,而是跳转到捕获异常的地方,这个地方可能对异常进行处理,也可能继续抛出异常。如下:
#include<iostream>
using std::endl;
using std::cout;
double div(double x, double y)
{
if (0 == y)
{
throw y; //抛出一个double类型的异常
}
return x / y;
}
void fun()
{
try
{
div(3.3, 0.0);
}
catch (double e)
{
throw e; //不处理,继续抛出
}
}
int main()
{
try
{
//div(3.3, 1.1); //不会抛出异常
//div(23.23, 0.0); //会抛出异常。
fun();
}
catch (double e)
{
cout << "除数为" << e << endl;
}
catch (...)
{
cout << "其它未知异常" << endl;
}
return 0;
}
这样直到main函数里才去处理异常。
异常的捕捉是严格匹配的,如果上面的代码中抛出一个int类型的异常,那么将会被catch(...)捕捉到。
为了增强程序的可读性,异常支持异常接口声明,我们可以在函数声明中列出可能抛出的所有异常类型。例如:
void fun(参数列表) throw(异常类型列表)
一旦声明了可抛出的异常类型,那么就不能抛出这些类型之外的异常。
可以参考这里:http://c.biancheng.net/view/422.html。本文的部分也是参考这里的。