异常基本概念

异常处理就是处理程序中的错误,所谓错误是指在程序运行的过程中发生的一些异常事件(如:除0退出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等)

c语言中处理异常

两种方法:

  1. 使用整形的返回值标识错误;

  2. 使用errno宏(可以简单的理解为一个全局整形变量)去记录错误,当然c++中仍然可以用这两种方法的。

  3. 这两种方法最大的缺陷就是会出现不一致问题,例如有些函数返回1表示成功,有些则返回0表示成功

  4. 还有一个缺点就是函数的返回值只有一个,你通过函数的返回值表示错误代码,那么函数就不能返回其他的值。当然,你也可以通过指针或者c++的引用来返回另外的值,但是这样可能会令你的程序比较难懂

c++中处理异常

  1. 函数的返回值可以忽略,但异常不可忽略,如果程序出现异常,但是没有被捕获,程序就会终止,这多少会促使程序员开发出来的程序更健壮一点,而如果使用C语言的errot宏或者函数的返回值,调用者都有可能忘记检查,从而没有对错进行处理,结果造成程序员莫名其妙的终止或出现错误的结果
  2. 整型返回值没有任何语义信息,而异常却包含语义信息,有时你从类名就能狗体现出来
  3. 整型返回值缺乏相关的上下文信息,异常作为一个类,可以拥有自己的成员,这些成员可以传递足够的信息
  4. 异常处理可以在调用跳级。这是一个代码编写时的问题:假设在有多个函数的调用栈中出现某个错误,使用整型返回码要求你在每一级函数中都要进行处理,而使用异常处理的栈展开机制,只需要在一处进行处理就可以,不需要每级函数都处理

异常的基本使用

  1. try试图执行try{}中的内容

  2. 在可能出现异常的地方 抛出异常 throw

  3. try下面catch捕获异常

  4. catch(捕获类型)...代表 所有其他类型

  5. 如果不想处理异常,继续向上抛出throw

  6. 如果没有任何处理异常的地方,那么成员调用terminate函数中断

  7. 自定义异常类,可以抛出自定义的对象

    #include<iostream>using namespace std;class myException  //自定义异常类
    {
    public:void printError(){cout << "自定义的异常" << endl;}
    };int myDevide(int a, int b)
    {if (b == 0){//如果b是异常,抛出异常//return -1;//throw - 1; 抛出int类型异常//throw 3.14;//抛出double类型异常   异常必须处理//throw 'a';throw myException(); //匿名对象}return a / b;
    }void test01(){int a = 10;int b = 0;//int ret = myDevide(a, b);//早期如果返回-1 无法区分到底是结果还是异常//c++中异常处理try{myDevide(a, b);}catch (int)//捕获异常{cout << "int 类型异常捕获" << endl;}catch (double){//如果不想处理这个异常,可以向继续向上抛出throw;cout << "double类型异常捕获" << endl;}catch (myException e){e.printError();}catch (...){cout << "其他异常类型捕获" << endl;}}int main()
    {try{test01();}catch (double) //如果异常都没处理,那么成员terminate函数,使程序中断{cout << "main函数中double类型异常捕获" << endl;}catch (...){cout << "main函数中其他异常类型捕获" << endl;}//test01();system("pause");return 0;
    }
    

总结:

  1. 若有异常则通过throw操作创建一个异常对象并抛出

  2. 将可能抛出异常的程序投放到try块之中

  3. 如果在try段执行期间没有引起异常,那么跟在try后面的catch字句就不会执行

  4. catch子句会根据出现的先后顺序被检查,匹配的catch语句捕获并处理异常(或继续抛出异常)

  5. 如果匹配的处理来找到,则运行函数terminate将自动被调用,其缺省功能调用abort终止程序

  6. 处理不了的异常,可以在catch的最后一个分支,使用throw,向上抛

  7. c++异常处理使得异常的引发和异常的处理不必在一个函数中,这样底层可以着重解决具体问题,而不必过多的考虑异常的处理,上层调用者可以在适当的位置设计对不同类型异常的处理

     #include<iostream>using namespace std;class myException  //自定义异常类{public:void printError(){cout << "自定义的异常" << endl;}};int myDevide(int a, int b){if (b == 0){//如果b是异常,抛出异常//return -1;//throw - 1; 抛出int类型异常//throw 3.14;//抛出double类型异常   异常必须处理//throw 'a';throw myException(); //匿名对象}return a / b;}void test01(){int a = 10;int b = 0;//int ret = myDevide(a, b);//早期如果返回-1 无法区分到底是结果还是异常//c++中异常处理try{myDevide(a, b);}catch (int)//捕获异常{cout << "int 类型异常捕获" << endl;}catch (double){//如果不想处理这个异常,可以向继续向上抛出throw;cout << "double类型异常捕获" << endl;}catch (myException e){e.printError();}catch (...){cout << "其他异常类型捕获" << endl;}}int main(){try{test01();}catch (double) //如果异常都没处理,那么成员terminate函数,使程序中断{cout << "main函数中double类型异常捕获" << endl;}catch (...){cout << "main函数中其他异常类型捕获" << endl;}//test01();system("pause");return 0;}
    

栈解旋

  1. 从try开始到throw抛出异常之前,所有栈上的对象都会被释放,这个过程称为栈解旋,构造析构顺序相反

  2. 栈上对象构造顺序与析构顺序相反

     class Person{public:Person(){cout << "Person构造" << endl;}~Person(){cout << "Person析构" << endl;}};int myDevide(int a, int b){if (b == 0){//如果b是异常,抛出异常//return -1;//throw - 1; 抛出int类型异常//throw 3.14;//抛出double类型异常   异常必须处理//throw 'a';//栈解旋//从try开始到throw抛出异常之前,所有栈上的对象都会被释放//这个过程称为栈解旋//构造析构顺序相反Person p1;Person p2;throw myException(); //匿名对象}return a / b;}
    

c++中的异常--1(基本概念, c语言中处理异常,c++中处理异常,异常的基本使用,栈解旋)相关推荐

  1. 以下对c语言函数的描述中正确的是,以下对C语言函数的有关描述中,正确的是

    摘要: 它决习定于的学后天,下语密切关系的能与社力是会文化有.关描透性的是起渗利尿可引.认的r默链接路径是(,述中在建点时立站.... 它决习定于的学后天,下语密切关系的能与社力是会文化有. 函数人感 ...

  2. 以下对c语言函数的描述中 错误的是,以下对C语言函数的有关描述中,正确的是....

    [填空题]对网络性能进行评估时,下语需要明确的主要性能指标是 ( 1 ) ,下语除了可用理论方法进行分析外,更多地需要实际测量,主要的测量方法是 ( 2 ) . (1)A.实际数据率 B.丢包率 C ...

  3. 下列c语言字符数组的描述中错误的是,下列对C语言字符数组的描述中错误的是( )...

    摘要: ,下列包括主要,方面三个.字符:下中国大学的是列不荷兰画家属于.若用二叉作为结构存储链表,数组述中曼树则该中总指针共有个空域哈夫,子结的叶点总夫曼设哈树中数为.... ,下列包括主要,方面三个 ...

  4. Java正则表达式中的捕获组的概念及相关API使用

    要弄清这三个方法,首先要弄清Java正则表达式中的捕获组的概念.捕获组也就是Pattern中以括号对"()"分割出的子Pattern.至于为什么要用捕获组呢,主要是为了能找出在一次 ...

  5. c语言如何编译及调试,中如何编译运行及调试C语言程序.doc

    中如何编译运行及调试C语言程序 VC++6.0中如何编译运行调试C语言程序 1.启动VC++6.0 (如下图) 2.单个源文件的编译运行 例如下面的源代码 #include void main() { ...

  6. norminv函数是什么matlab,matlab中的函数norminv能否用C语言实现

    matlab中的函数norminv可不可以用C语言实现? 对于matlab中的函数norminv,C语言中有没有函数可以完成类似的功能?没有的话,用C语言要如何实现呢? matlab中的函数normi ...

  7. [ARM异常]-ARMV8-aarch64异常和中断处理概念详细介绍

    ★★★ 个人博客导读首页-点击此处 ★★★ 文章目录 1.异常和中断的概念 2.异常产生的方法: (1).Abort : (2).Reset (3).同步异常 (4).异步异常(中断) 3.同步异常和 ...

  8. 多态的概念、对象上下转型、多态的应用、异常(异常概念、异常分类、java异常处理机制、try...catch...finally、throw和throws、自定义异常)

    多态的概念: 多态性是指同一个操作作用于某一类对象,可以有不同的解释,产生不同的执行结果. 多态存在的三个必要条件: ① 需要存在继承或实现关系 ② 同样的方法调用而执行不同的操作.运行不同代码(重写 ...

  9. C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项

    在 2020 年的最后一天,博客园发起了一个开源项目:基于 .NET 的博客引擎 fluss,我抽空把源码下载下来看了下,发现在属性的定义中,有很多地方都用到了 null!,如下图所示: 这是什么用法 ...

最新文章

  1. bzoj1174 Toponyms
  2. 【转】MySQL实现Oracle里的 rank()over(ORDER BY) 功能
  3. 验证手机号码归属地_手机号码归属地能否取消? 工信部回复了
  4. yml php,使用 docker-compose.yml 快速搭建php开发环境
  5. 2019牛客多校Monotonic Matrix
  6. http 请求头 header Referer 含义和作用
  7. Android Studio中XML注释错误问题
  8. 从零开发微信公众号(PC)
  9. WBS工作分解结构法
  10. 成语答题小程序源码安装 开源的成语答题小程序
  11. Python3爬虫(4)--抓取考生的四六级成绩
  12. 2021武汉建港中学高考成绩查询,武汉2021年部分示范高中四月调考分数线(预估)...
  13. ArcGIS面矢量挖洞
  14. 使用Mailgun Store():应用程序传入电子邮件的临时邮箱
  15. 八字易经算法之用JAVA实现生旺死绝和十神
  16. 葡萄城报表介绍:自由报表
  17. python模拟登录URP教务系统评教
  18. PPP with MPPE协议
  19. SQLyog Ultimate软件安装教程
  20. OllyDbg使用教程

热门文章

  1. H5前期知识点总结 9月12日
  2. mysql 中文乱码解决方法
  3. HDU - 4497 GCD and LCM
  4. 常用Jquery前端操作
  5. memcpy、memmove、memset、memchr、memcmp、strstr详解
  6. Freemarker宏和函数的用法和区别
  7. 关于window.history.back()后退问题
  8. WebClient与WebRequest差异
  9. PowerSocket对象与HostName
  10. php 水平测试,测试您的 PHP 水平的题目_PHP教程