C++异常处理机制(throw、try、catch、finally)
⼀、什么是异常处理
  ⼀句话:异常处理就是处理程序中的错误。
程序运⾏时常会碰到⼀些异常情况,例如:
1、做除法的时候除数为 0;
2、⽤户输⼊年龄时输⼊了⼀个负数;
3、⽤ new 运算符动态分配空间时,空间不够导致⽆法分配;
4、访问数组元素时,下标越界;打开⽂件读取时,⽂件不存在。
这些异常情况,如果不能发现并加以处理,很可能会导致程序崩溃。
⼆、异常处理机制
1、当发⽣异常,程序⽆法沿着正常的顺序执⾏下去的时候,⽴即结束程序可能并不妥当。我们需要给程序提供另外⼀条可以安全退出
的路径,
在结束前做⼀些必要的⼯作,如将内存中的数据写⼊⽂件、关闭打开的⽂件、释放动态分配的内存空间等。
2、当发⽣异常的时候,程序马上处理可能并不妥当(⼀个异常有多种处理⽅法,或者⾃⼰⽆法处理异常),需要将这个异常抛出给他
的上级(直接调⽤者),
由上级决定如何处理。或者是⾃⼰不处理再转交给它的上级去处理,⼀直可以转交到最外层的main()函数
3、另外,异常的分散处理不利于代码的维护,尤其是对于在不同地⽅发⽣的同⼀种异常,都要编写相同的处理代码也是⼀种不必要的
重复和冗余。
如果能在发⽣各种异常时让程序都执⾏到同⼀个地⽅,这个地⽅能够对异常进⾏集中处理,则程序就会更容易编写、维护。
在引⼊异常处理机制之前,异常的处理⽅式有两种⽅法
  1、使⽤整型的返回值标识错误;
  2、使⽤errno宏(可以简单的理解为⼀个全局整型变量)去记录错误。当然C++中仍然是可以⽤这两种⽅法的。
这两种⽅法最⼤的缺陷就是会出现不⼀致问题。例如有些函数返回1表⽰成功,返回0表⽰出错;⽽有些函数返回0表⽰成功,返回⾮0表⽰出错。
还有⼀个缺点就是函数的返回值只有⼀个,你通过函数的返回值表⽰错误代码,那么函数就不能返回其他的值。
鉴于上述原因,C++引⼊了异常处理机制
异常处理流程
C++ 异常处理涉及到三个关键字:try、catch、throw。
1、throw:当问题出现时,程序会抛出⼀个异常。这是通过使⽤ throw 关键字来完成的。
2、try: try 块中的代码标识将被激活的特定异常。它后⾯通常跟着⼀个或多个 catch 块。
3、catch:在您想要处理问题的地⽅,通过异常处理程序捕获异常。catch 关键字⽤于捕获异常。
4、finally:关键字finally放在catch之后,如果异常没有被catch捕获,会使⽤关键字去清理释放资源
  如果有⼀个块抛出⼀个异常,捕获异常的⽅法会使⽤ try 和 catch 关键字。try 块中放置可能抛出异常的代码(判断异常的类型),try 块中的代码被称为保护代码。
  catch后⾯对应每个异常的处理⽅法。
  以除法除0举例。代码如下所⽰:
try catch的使用方法#include <iostream>
using namespace std;
double division(int a, int b)
{
if (b == 0)
{
throw"Division by zero condition!";
}
return (a / b);
}
int main()
{
int x = 50;
int y = 0;
double z = 0;
//try\catch的使⽤和switch\case的使⽤类似
try {
z = division(x, y);
cout << z << endl;
}
catch (const char* msg) {
cerr << msg << endl;
}
  //finally{}
return0;
}
三、⼏个概念
1、栈展开
栈展开指的是:当异常抛出后,匹配catch的过程。
抛出异常时,将暂停当前函数的执⾏,开始查匹配的catch⼦句。沿着函数的嵌套调⽤链向上查,直到到⼀个匹配的catch⼦句,或者不到匹配的catch⼦句。
栈展开的时候,会通过析构函数或者是delete销毁局部对象(从开始匹配位置到确认匹配这⼀段中间位置的资源会被释放)
2、析构函数应该从不抛出异常。
如果析构函数中出现异常,那么就应该在析构函数内部将这个异常进⾏处理,⽽不是将异常抛出去。
为什么不应该?抛出异常的就是栈展开的过程,⽽栈展开会调⽤析构函数销毁局部对象,这样多次调⽤析构函数会导致程序崩溃(内存泄漏)
3、构造函数可以抛出异常
  当构造函数内出现异常,可以选择将异常抛出,在栈展开的过程调⽤析构函数释放已申请的内存,也可以在内部将异常处理,⼿动调⽤delete释放
4、catch捕获所有异常
语法:在catch语句中,使⽤三个点(…)。即写成:catch (…)  这⾥三个点是“通配符”,类似可变长形式参数。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。