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

异常基本概念

异常处理就是处理程序中的错误,所谓错误是指在程序运行的过程中发生的一些异常事件(如:除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;}
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RGB、YUV和YCbCr

之前对RGB、YUV和YCbCr一直没有清晰的理解和认识&#xff0c;今天打算做一个小结&#xff0c;结合网上的文章谈谈自己的看法&#xff0c;也希望有机会看到这篇文章的人能指点一二&#xff0c;相互交流&#xff0c;共同进步。 首先要说明&#xff0c;上述的RGB、YUV和YCbCr都是人…

c++中的异常---2(异常接口声明,异常变量的生命周期,异常的多态使用)

异常接口声明 为了加强程序的可读性&#xff0c;可以在函数声明中列出可能抛出异常的所有类型&#xff0c;例如&#xff1a;void func() throw(A,B,C);这个函数func能够且只能抛出类型A,B,C及其子类的异常如果在函数声明中没有包含异常接口声明&#xff0c;则此函数可以抛任何…

c++中的异常---3(系统标准异常库,编写自己异常类)

系统标准异常库 #incldue out_of_range 等… #include<iostream>#include<string>using namespace std;//系统提供标准异常#include<stdexcept>class Person{public:Person(string name, int age){this->m_Name name;//年龄做检测if (age<0 || age&g…

H.264中IDR帧和I帧区别

IDR&#xff08;Instantaneous Decoding Refresh&#xff09;--即时解码刷新。I和IDR帧都是使用帧内预测的。它们都是同一个东西而已,在编码和解码中为了方便&#xff0c;要首个I帧和其他I帧区别开&#xff0c;所以才把第一个首个I帧叫IDR&#xff0c;这样就方便控制编码和解码…

c++中的IO流(流的概念和流类库的结构,标准的输入输出流)

流的概念和流类库的结构 程序的输入指的是从输入文件将数据传送给程序&#xff0c;程序的输出指的是从程序将数据传送给输出文件 c输入输出包含以下三个方面的内容 对系统指定的标准设备的输入输出。即从键盘输入数据&#xff0c;输出到显示器屏幕&#xff0c;这种输入输出称…

MTD应用学习札记

今天做升级方案用到了mtd-utils中的flash_eraseall和flash_cp两个工具&#xff0c;在进行方案验证的时候&#xff0c;遭遇到各种不解和疑惑&#xff0c;因对MTD的原理不熟悉&#xff0c;所以只能多次尝试&#xff0c;虽然最后把方案搞定了&#xff0c;不过觉得MTD中的mtd和mtdb…

c++中的文件读写的操作

写文件 ofstreamopen指定打开方式isopen判断是否打开成功ifs<<“数据”ofs.close&#xff08;&#xff09; 读文件 ifstream ifs 指定打开方式ios::in isopen判断是否打开成功 读取有三种方式 #include<iostream>using namespace std;//文件读写头文件#incl…

udhcpc命令

由于要使用网络通讯&#xff0c;所以不可避免的要用到dhcp。理想的网络通讯方式是下面3种都要支持: 1,接入已有网络。这便要求可以作为dhcp客户端。 2,作为DHCP服务器&#xff0c;动态分配IP。 3,指定固定IP 第3种情况没有什么好说的&#xff0c;简单说下前2种情况。 使用步骤&…

c++的STL--1概念通述

STL的概念 什么是STL? STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且 是一个包罗数据结构与算法的软件框架。 STL从广义上分为&#xff1a;容器(container)&#xff0c;算法(algorit…

socket通信和异常处理札记

Linux socket通信出现CLOSE_WAIT状态的原因与解决方法 这个问题之前没有怎么留意过&#xff0c;是最近在面试过程中遇到的一个问题&#xff0c;面了两家公司&#xff0c;两家公司竟然都面到到了这个问题&#xff0c;不得不使我开始关注这个问题。说起CLOSE_WAIT状态&#xff0c…

mac 下使用wireshark监听网络上的数据

分三个步骤&#xff1a; 1.wireshark安装 wireshark运行需要mac上安装X11&#xff0c;mac 10.8的系统上默认是没有X11的。先去http://xquartz.macosforge.org/landing/下载最新的 xquartz安装&#xff0c;安装好就有X11了。 wireshark的下载&#xff0c;网…

c++的vector容器

vector容器概念 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0c;而且它…

嵌入式Linux下3G USB Modem的使用

busybox中需打开&#xff1a;wc&#xff0c;pidof&#xff1b; busybox中shell下打开getopts 百度搜索“Serial connection established. using channel 1”包含大量问题解答 2013-12-22 0个评论 收藏 我要投稿 一.ARM-Linux ARM-Linux-2.6.17 3G USB Modem:hu…

新一代数据库技术

新一代非关系型数据库有以下5个主要类型&#xff1a; 面向文件存储&#xff1a;适用于存储海量文件&#xff0c;代表产品MongoDb 列存储(wide column store/column-family)数据库&#xff1a;快速查找相关数据&#xff0c;相关数据被放在同一列中&#xff0c;代表产品Cassandra…

c++中stack容器

Stack 简介 stack 是堆栈容器&#xff0c;是一种“先进后出”的容器。stack 是简单地装饰 deque 容器而成为另外的一种容器。#include stack没有迭代器 Stack所有元素的进出都必须符合“先进后出”的条件&#xff0c;只有stack顶端的元素&#xff0c;才有机会被外界取用&am…

详解udev

如果你使用Linux比较长时间了&#xff0c;那你就知道&#xff0c;在对待设备文件这块&#xff0c;Linux改变了几次策略。在Linux早期&#xff0c;设备文件仅仅是是一些带有适当的属性集的普通文件&#xff0c;它由mknod命令创建&#xff0c;文件存放在/dev目录下。后来&#xf…

c++中的queue容器

queue容器 队列是一种容器适配器&#xff0c;专门用于在FIFO上下文(先进先出)中操作&#xff0c;其中从容器一端插入元素&#xff0c;另一端 提取元素。 队列作为容器适配器实现&#xff0c;容器适配器即将特定容器类封装作为其底层容器类&#xff0c;queue提供一组特定的 成员…

NAU8810相关问题

1.ADC和DAC有什么区别&#xff1f; 不&#xff0c;这不是一个“愚弄人的”问题或脑筋急转弯&#xff0c;并且我认为我们的读者都非常清楚模数转换器(ADC)及数模转换器(DAC)的基本功能。 但在如何使用这些转换器以及人们的认知度上也存在着哲理性区别。用最简单的话讲&#xff0…

c++中list容器

list概念 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个元素和后一个元素。list与for…

Linux中rc的含义

在Linux中&#xff0c;最为常用的缩略语也许是“rc”&#xff0c;它是“runcomm”的缩写――即名词“run command”(运行命令)的简写。rc”是任何脚本类文件的后缀&#xff0c;这些脚本通常在程序的启动阶段被调用&#xff0c;通常是Linux系统启动时。如/etc/rc&#xff08;连接…