【C++基础】异常匹配与内建异常类

目录

  • 异常匹配
    • catch: 按异常类型匹配
    • 为何要使用异常类
  • 内建异常类
    • 标准库中的异常基类
    • 标准库中的异常类
    • 例1:vector下标访问越界out_of_range异常
    • 例2:内存分配失败bad_alloc异常
    • 例3:侧向转换失败bad_cast异常类
    • 几种情况,使用对应异常

异常匹配

catch: 按异常类型匹配

已知try是监视可能出现问题的代码,throw是扔出问题,catch是看扔出的问题是否和它的类型匹配,如果是匹配那么就抓住问题进行处理。
这里的类型使用传引用,避免拷贝浪费。

catch ( ExceptionType& parameter ) { /* 处理异常 */ }

若try{}中所抛异常类型与catch()的参数类型(ExceptionType)匹配,则进入catch块
若对异常对象的内容不感兴趣,可省略catch参数,只保留类型。
如:

catch ( ExceptionType& ) { /* 处理异常 */ }

举例:
f1()抛出整型异常。
f2()是要申请28G内存,如果电脑内存不够,执行代码会出错,抛出bad_alloc异常。这是C++规定的,new出现问题就会抛出bad_alloc异常。bad_alloc是C++异常类exception基类的派生类。

void f1() { throw 100; }
void f2() { for (int i = 1; i <= 100; i++) new int[70000000]; }

对于f1的两种处理:

try { f1(); }
catch (int) { //仅有类型cout << "Error" << endl;
}try { f1(); }
catch (int& e) { //类型+参数cout << e << endl;
}

对于f2的两种处理:
注意e.what()是exception类内部的一个虚函数,返回的是一个指针,指向一个字符串,包含了异常的解释信息。


try { f2(); } 
catch (bad_alloc) {cout << "new failed" << endl;
}
try { f2(); } 
catch (bad_alloc &e) {cout << "Exception: " << e.what() << endl;
}

为何要使用异常类

整数作为异常类型,只能获取整数的信息。
不使用异常类,则捕获的异常所能传递的信息量很少。

try {// ...
}
catch (int e) {//do something with e
}

使用异常类,则可以在抛出异常时传递很多信息,在捕获异常时接收这些信息。

class Beautiful {string name;string hometown;int    salary;string misdoing;
// ………… 
}
try {// ...
}
catch (Beautiful object) {//do something with object
}

内建异常类

标准库中的异常基类

exception 是标准库所有异常类的基类
使用异常类需要包括头文件 #include <exception>
class exception需要注意的部分如下:

exception(); // 构造函数
virtual const char* what(); //返回解释性字符串
what()返回的指针指向拥有解释信息的空终止字符串的指针。该指针保证在获取它的异常对象被销毁前,或在调用该异常对象的非静态成员函数前合法

标准库中的异常类

在使用所有标准库异常类的时候,都必须附加std名字空间。
在这里插入图片描述
runtime_error与logic_error的使用区别
来自wiki的解释:

逻辑错误:(有时称为语义错误)是程序中的一个错误,它会导致程序错误运行,但不会异常终止(或崩溃)。逻辑错误会产生非预期或不希望的输出或其他行为,尽管它可能不会立即被识别。
编译语言和解释语言都会出现逻辑错误。与有语法错误的程序不同,有逻辑错误的程序在语言中是有效的程序,尽管它的行为不符合预期。
运行时错误:一个错误在程序执行过程中发生的。相反,编译时错误发生在程序编译时。运行时错误表示程序中的错误或设计人员预期的问题,但却无能为力。例如,内存不足通常会导致运行时错误。

例1:vector下标访问越界out_of_range异常

vector有许多种访问元素的方式,其中[]下标访问不会做越界检查,at()会做越界检查。
在这里插入图片描述
在这里插入图片描述
我们将它截获
在这里插入图片描述

例2:内存分配失败bad_alloc异常

#include<iostream>
using namespace std;
int main()
{for( int i = 0; i < 10000; i++){auto *p = new long long int [70000];cout << i << "array" << endl;}return 0;
}

在这里插入图片描述
进行捕获

#include<iostream>
#include <exception>
#include <stdexcept>
#include <new>
using namespace std;
int main()
{try {for (int i = 0; i < 10000; i++){auto* p = new long long int[70000];cout << i << "array" << endl;}}catch (bad_alloc& e){cout << "exception " << e.what() << endl;}return 0;
}

exception bad allocation程序正常退出。

例3:侧向转换失败bad_cast异常类

创建基类student
创建派生类Undergraduate和Graduate
主函数中用dynamic_cast 将Undergraduate类型转换为Graduate类型.
dynamic_cast只有在做引用类型转换时候转换失败才会抛出异常。使用指针类型时,如果转换失败会返回nullptr

#include <iostream>
#include <exception>
#include <stdexcept>using namespace std;class Student {
public:Student() = default;virtual void foo() {};
};
class Undergraduate : public Student {};
class Graduate : public Student {};
int main()
{Undergraduate u;Graduate g;Student *s1 = &u;Student *s2 = &g;//正常操作,p指针不为nullptrGraduate *p = dynamic_cast<Graduate *>(s2);//转化不成功,p2指针为nullptrGraduate *p2 = dynamic_cast<Graduate *>(s1);if(p2 == nullptr){cout << "cast s1 to Graduate* failed " << endl;}else{cout << "cast s1 to Graduate* succeeded " << endl;}//引用,抛异常try{Graduate &r1 = dynamic_cast<Graduate &> (u);}catch (bad_cast & e){cout << "Exception: " << e.what() << endl;}return 0;
}

在这里插入图片描述

几种情况,使用对应异常

1、除法运算中除数为0;
:invalid_argument

2、在只读文件系统中以写模式打开一个文件流;
:filesystem::filesystem_error
3、 数组a的容量为5,向 a[5] 中写入数据;
:out_of_range

4、用 new 申请内存失败;
:bad_array_new_length
5、将A指针类型转换为B指针类型失败;
:bad_any_cast
6、将 1234567 这个整数存到一个 short int 类型的变量中(在32位C++编译器中编译)
:length_error

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

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

相关文章

scala 访问修饰符_Scala中的访问修饰符

scala 访问修饰符Access modifiers are used in order to restrict the usage of a member function to a class or a package. Using access modifiers data hiding takes place which is a very important concept of OOPs. 访问修饰符用于将成员函数的使用限制为类或包。 使…

小试---EF5.0入门实例1

现在做个小练习吧~~~ 第一步&#xff1a;首先新建一个数据库名字为Test;数据库里面只有一个表UserTable 脚本为&#xff1a; USE [master] GO /****** 对象: Database [Test] 脚本日期: 12/15/2013 18:51:54 ******/ CREATE DATABASE [Test] ON PRIMARY ( NAME NTest, F…

iScroll4 禁止select等页面元素默认事件的解决方法 转

iScroll4 禁止select等页面元素默认事件的解决方法起因在于onBeforeScrollStart : function(e){ e.preventDefault(); },这一行&#xff0c;iSroll禁止了事件的默认行为&#xff0c;导致select&#xff0c;option&#xff0c;textarea等元素无法点击。解决方法也很简单&#xf…

C++中比较两个浮点数是否相等

来源&#xff1a; https://stackoverflow.com/a/37686/3242645 代码&#xff1a; #include <cmath> #include <limits> bool AreSame(double a, double b) {return std::fabs(a - b) < std::numeric_limits<double>::epsilon(); }

MPEG的完整形式是什么?

MPEG&#xff1a;运动图像专家组 (MPEG: Moving Picture Experts Group) MPEG is an abbreviation of Moving Picture Experts Group. It is a working group of authorities that is founded to establish standards for audio and video compression and transmission. The a…

正则 去除html标记

//string regexstr "<[^>]*>"; //去除所有的标签 //"<script[^>]*?>.*?</script>" //去除所有脚本&#xff0c;中间部分也删除 // string regexstr "<img[^>]*>"; //去除图片的正则 // string regexstr &…

自画PopMenu弹出

BorderColor:TColor; //边框颜色FillColor:TColor; //未选中填充颜色TextColor:TColor; //未选中字体颜色SelectTextColor:TColor; //选中字体颜色SelectFillColor:TColor; //选中填充颜色SideBuffer:Integer; //边框宽度procedure TForm1.FormCreate(Sender: TObject); b…

安利一款倒计时插件---雨滴桌面

内容来自B站(搜索Rainmeter即可)&#xff0c;里面教程很多&#xff0c;因为视频看的有点麻烦&#xff0c;故进行了整理 一、下载安装包、解压、安装 免费下载连接&#xff0c;不需要积分 skin文件夹存放皮肤的一些配置文件&#xff0c;因为原本皮肤太low了 第二个是可执行文…

【C++基础】自定义异常类与多重捕获

目录自定义异常类构建过程例&#xff1a;Vec3D类的数组下标越界的异常类捕获多种无关异常不同的异常的捕获捕获派生异常异常处理的次序例子&#xff1a;多重捕获异常类catch块的参数类型可以不用引用类型吗?自定义异常类 自定义异常类通常由exception或其后代类派生。这样我们…

gprs 睡眠模式_GPRS的完整形式是什么?

gprs 睡眠模式GPRS&#xff1a;通用分组无线业务 (GPRS: General Packet Radio Service) GPRS is an abbreviation of General Packet Radio Service. It is a non-voice, high-level speed packet switching technology planned for GSM networks. On 2G and 3G cellular tran…

int main(int argc,char* argv[])讲解

分类&#xff1a; 学习笔记2011-11-07 21:502354人阅读评论(0)收藏举报dos编译器pathunixcommandc在最近学习中老是遇到 int main(int argc,char* argv[])&#xff0c;以为就是简单的参数应用了&#xff0c;但是看代码是没能理解参数的具体传递过程&#xff0c;上网…

Maven实战(七)——常用Maven插件介绍(上)

我们都知道Maven本质上是一个插件框架&#xff0c;它的核心并不执行任何具体的构建任务&#xff0c;所有这些任务都交给插件来完成&#xff0c;例如编译源代码是由maven-compiler-plugin完成的。进一步说&#xff0c;每个任务对应了一个插件目标&#xff08;goal&#xff09;&a…

【设计模式之美】<Reading Notes>抽象类与接口

抽象类特性 1、抽象类不允许被实例化&#xff0c;只能被继承。 2、抽象类可以包含属性和方法。方法既可以包含代码实现&#xff0c;也可以不包含代码实现。不包含代码实现的方法叫做抽象方法。 3、子类继承抽象类&#xff0c;必须实现抽象类中的所有抽象方法。 接口特性 1、…

多线程之间共享数据的实现

1&#xff1a;如果每个线程执行的代码相同&#xff0c;可以使用同一个Runnable对象&#xff0c;然后将共享的数据放在Runnable里面&#xff0c;来实现数据的共享。 例如买票系统... package com.cn.gbx;import java.util.Date; import java.util.Random; import java.util.Time…

AIX的完整形式是什么?

AIX&#xff1a;高级交互式主管 (AIX: Advanced Interactive Executive) AIX is an abbreviation of "Advanced Interactive Executive". AIX是“ Advanced Interactive Executive”的缩写 。 It is a progression sequence of proprietary UNIX operating systems …

c#生成随机字符串 用做批量申请账号时的随机密码还是相当不错的

//随机字符串生成器的主要功能如下&#xff1a; //1、支持自定义字符串长度 //2、支持自定义是否包含数字 //3、支持自定义是否包含小写字母 //4、支持自定义是否包含大写字母 //5、支持自定义是否包含特殊符号 //6、支持自定义字符…

【C++基础】C++11的noexcept声明符 与 异常传播

目录C noexcept&#xff1a;1、用途2、用法1、noexcept声明符的用法&#xff1a;2、noexcept运算符的用法异常传播1、异常传播的定义2、异常传播中的规则3、异常传播的代价C noexcept&#xff1a; 1、用途 C11使用noexcept指明函数是否抛出异常&#xff1a; 若函数不抛异常&a…

使用IndexReader.repen提高搜索速度

1,使用indexreader创建indexsearcher. 2,indexsearcher在使用完了以后不要关闭. 3.使用indexreader.isCurrent()判断索引是否被indexwriter改动. 4,如果索引被改动,indexsearcher.close()先前那个,然后new indexsearcher(indexreader). 传string给searcher,searcher会维护一个内…

CSS中的文本格式

CSS文字格式 (CSS text formatting) CSS text properties allow you to style your text in various ways very easily. Such as color, alignment, spacing, direction, etc. CSS文本属性使您可以轻松地以各种方式设置文本样式。 例如颜色 &#xff0c; 对齐方式 &#xff0c;…

【C++基础】重抛异常与异常的使用场景

重抛异常 异常处理程序可以重新抛出异常。 当它无法处理该异常&#xff0c;或想通知它的调用者发生了一个异常&#xff0c;此时就需要重抛异常&#xff1a; 1、抛出捕获的异常 try {// statements; } catch (TheException &ex) {// Do something;throw; }2、重新抛出另一…