C++异常机制知识点
在这里总结一下,C++中的异常机制,以及如何使用异常的知识点
C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,由其上一级处理。如此逐级上传,直到最高一级还无法处理的话,运行系统会自动调用系统函数terminate,由它调用abort终止程序。这样的异常处理方法使得异常引发和处理机制分离,而不在同一个函数中处理。这使得底层函数只需要解决实际的任务,而不必过多考虑对异常的处理,而把异常处理的任务交给上一层函数去处理。
总结C++异常机制的用法概念
首先异常机制中最重要的三个关键字就是:throw try catch。
Throw抛出异常,try 包含异常模块,catch 捕捉抛出的异常,三者各有各的分工,集成在一起就构成了异常的基本机制。
我们为什么要检测异常,抛出异常,?
程序做错误检查是必要的,通常我们可以通过返回值告诉客户有了错误,不过异常提供了更加方便的手段和丰富的信息。举个例子,一个游戏软件,需要判断你在打游戏中选择的关口(类似于地下城勇士中勇士级,王者级等),其中每一个关口都对应这一个ID(这是必须的),当你等级不够时,不能选择高等级的,此时就要抛出一个异常,提示你等级不够,不可以进入,例子可能有些不恰当,但足以说明使用异常处理的重要性。废话不说了,下面详细介绍下如何使用异常处理。
如果在try语句块的程序段中(包括在其中调用的函数)发现了异常,且抛弃了该异常,则这个异常就可以被try语句块后的某个catch语句所捕获并处理,捕获和处理的条件是被抛弃的异常的类型与catch语句的异常类型相匹配。由于C++使用数据类型来区分不同的异常,因此在判断异常时,throw语句中的表达式的值就没有实际意义,而表达式的类型就特别重要
以异常语句如下:
try
{
可能会出异常的函数或者语句,判断是否出现异常,抛出异常
}
Catch(异常类型 [参数名字] )
{
捕捉异常
}
其中catch语句可以有多个,以捕捉不同的异常。
(1)异常类型我们可以使用自己定义的,我们写一个程序,除法程序,除数为零,自定义抛出异常类型。
#include<iostream>
#include<stdexcept>
using namespace std; class divide_zero //自定义异常类型
{}; int divide(int c, int d) //定义函数,异常类型说明 此处不写,则说明是此函数有可能抛出各种异常
{
if(d==0)
throw divide_zero();//抛出异常类型为 除零异常类型
cout<<"Correct the result is"<<c/d<<endl;
return 0;
} int main()
{
int a,b;
//使用自定义异常类型
cout<<"Please enter the two different integer "<<endl;
cin>>a>>b;
try
{
divide(a,b); //可能发生异常的函数
}
catch(divide_zero) //捕捉到除数为零的异常
{
cout<<"Division by zero"<<endl;
}
return 0;
}
运行结果是:
(2)异常类型可以是我们定义的类,我们也可以定义异常类型是基本数据类型,为此,我们修改上述代码
#include<iostream>
#include<stdexcept>
using namespace std; int divide(int x,int y)
{
if(y==0)
throw y;
cout<<"Correct the result is"<<x/y<<endl;
return 0;
} int main()
{
//自定义类型之使用基本数据类型
try
{
divide(1,0);
}
catch(<span style="color:#ff0000;">int</span>) //<span style="color:#ff0000;">因为除数是整形所以抛出异常时类型是整形才能捕捉(0也是整形)</span>
{
cerr<<"error of dividing zero./n";
exit(1); //异常退出程序
}
}
运行结果是:
此时我们也可以用C++的标准异常,为此我们修改上面代码,我们先介绍下C++的标准异常类,使用C++提供给我们的标准异常时,我们需要包含头文件#include<stdexcept>
以下是我查找的C++标准异常类型,引用一个大神的文章
namespace std
{
//exception派生
class logic_error; //逻辑错误,在程序运行前可以检测出来
//logic_error派生
class domain_error; //违反了前置条件
class invalid_argument; //指出函数的一个无效参数
class length_error; //指出有一个超过类型size_t的最大可表现值长度的对象的企图
class out_of_range; //参数越界
class bad_cast; //在运行时类型识别中有一个无效的dynamic_cast表达式
class bad_typeid; //报告在表达试typeid(*p)中有一个空指针p
//exception派生
class runtime_error; //运行时错误,仅在程序运行中检测到
//runtime_error派生
class range_error; //违反后置条件
class overflow_error; //报告一个算术溢出
class bad_alloc; //存储分配错误
}
其中的一个重要函数为what(),它返回一个表示异常的字符串指针。
标准库异常类定义在以下四个头文件中
1、exception头文件:定义了最常见的标准异常类,其类名为exception。只通知异常的产生,但不会提供更多的信息
2、stdexcept头文件定义了以下几种常见异常类
函数 功能或作用
exception 最常见的问题
runtime_error 运行时错误:仅在运行时才能检测到的问题
range_error 运行时错误:生成的结果超出了有意义的值域范围
overflow_error 运行时错误:计算上溢
underflow_error 运行时错误:计算下溢
logic_error 逻辑错误:可在运行前检测到的问题
domain_error 逻辑错误:参数的结果值不存在
invalid_argument 逻辑错误:不合适的参数
length_error 逻辑错误:试图生成一个超出该类型最大长度的对象
out_of_range 逻辑错误:使用一个超出有效范围的值
了解完后,我们开始编写程序,在此我们只是简单地使用下标准异常类。
#include<iostream>
#include<stdexcept>
using namespace std; int main()
{
//抛出一个小小的异常 使用C++标准异常类
int a,b;
cout<<"Please enter the two different integer "<<endl;
while(cin>>a>>b)
{
try
{
if(b==0)
throw runtime_error("两者不可以相等"); }
catch(runtime_error err)
{
cout<<err.what()<<endl;
}
cout<<"请继续输入"<<endl; }
return 0;
}
运行结果是:
异常的接口声明
为了加强程序的可读性,使函数的用户能够方便地知道所使用的函数会抛出哪些异常,可以在函数的声明中列出这个函数可能抛出的所有异常类型,例如:
void fun() throw( A,B,C,D);
这表明函数fun()可能并且只可能抛出类型(A,B,C,D)及其子类型的异常。如果在函数的声明中没有包括异常的接口声明,则此函数可以抛出任何类型的异常,例如:
void fun();
一个不会抛出任何类型异常的函数可以进行如下形式的声明:
void fun() thow();
此时一定要注意:编译器不会对异常说明进行检测,异常说明更多的是写给函数的用户看。
而在一开始函数异常说明的类型与实际抛出的异常类型不匹配的情况中,同样由于“编译器不会对异常说明进行检测”的原因,所以编译通过,异常机制运行正常。比如说,你的声明的类型是整形,结果还是让除数为零的异常接收到了,有人感觉很奇怪,其原因就在于此。
C++异常机制知识点的更多相关文章
- Atitit 异常机制与异常处理的原理与概论
Atitit 异常机制与异常处理的原理与概论 1. 异常vs 返回码1 1.1. 返回码模式的处理 (瀑布if 跳到失败1 1.2. 终止模式 vs 恢复模式(asp2 1.3. 异常机制的设计原理 ...
- C++ 异常机制分析
C++异常机制概述 异常处理是C++的一项语言机制,用于在程序中处理异常事件.异常事件在C++中表示为异常对象.异常事件发生时,程序使用throw关键字抛出异常表达式,抛出点称为异常出现点,由操作系统 ...
- 【转载】C++异常机制的学习
参考了这篇文章:http://blog.chinaunix.net/uid-24517549-id-4079174.html 关于线程 进程和线程的概念相信各位看官早已耳熟能详.在这里,我只想带大家回 ...
- Java异常机制
Java异常分类 异常表明程序运行发生了意外,导致正常流程发生错误,例如数学上的除0,打开一个文件但此文件实际不存在,用户输入非法的参数等.在C语言中我们处理这类事件一般是将其与代码正常的流程放在一起 ...
- 黑马程序员——【Java基础】——面向对象(二)异常机制、包(Package)
---------- android培训.java培训.期待与您交流! ---------- 一.异常机制 (一)异常概述 1.异常:就是程序在运行时出现不正常情况. 2.异常类:程序在运行时,出现的 ...
- C 几种异常机制简单讲述
引言 这是关于C中如何使用异常机制的讨论.顺带讲一讲C中魔法函数的setjmp内部机制.通过它实现高级的异常try...catch. 允许我先扯一段面试题. 对于计算机面试题. 算法题等.觉得还是有意 ...
- [转载]C++异常机制的实现方式和开销分析
原文章网址:http://baiy.cn/doc/cpp/inside_exception.htm C++异常机制的实现方式和开销分析 白杨 http://baiy.cn 在我几年前开始写<C+ ...
- c++异常机制实现原理
今天突然看到一篇文章,讲异常机制的实现,所以分享一下:http://baiy.cn/doc/cpp/inside_exception.htm 内容讲的很深,但是编译器的实现是不是真是这样就不知道了,我 ...
- java中的异常机制(编译时异常)
/ * 1 异常机制的原理 * 异常是什么:就是错误的另外一种说法; * 在java中,有一个专门模拟所有异常的类,所有的异常都必须继承这个类:Throwable; * 本质是:当程序出错以后,jvm ...
随机推荐
- JS常用的设计模式(15)—— 职责链模式
职责链模式是一个对象A向另一个对象B发起请求,如果B不处理,可以把请求转给C,如果C不处理,又可以把请求转给D.一直到有一个对象愿意处理这个请求为止. 打个比方,客户让老板写个php程序.老板肯定不写 ...
- sublime Text2 2.0.2 build 2221 64位 破解(已测试)
近终于找到 sublime Text2 升级到 2.0.2 build 2221 64位 的破破解 输入注册码就成了 ----- BEGIN LICENSE ----- Andrew Weber S ...
- leetcode 118
118. Pascal's Triangle Given numRows, generate the first numRows of Pascal's triangle. For example, ...
- JSON-JQuery常用技巧
1:Jquery对象选择查找 var group = $(".classeslist li"); class 为 classeslist 内部 的所有 li 元素对象 遍历: fo ...
- 图片轮播jQuery
<script type="text/javascript"> //图片轮播 var bannerIndex = 0; ba ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- js-布尔值
1.任何JavaScript的值都可以转换为布尔值 下面这些将会转换为false(假值): undefined null 0 -0 NaN "" //空字符串 所有其他值,包括所有 ...
- php qr生成二维码
二维码就是用在平面上用特定的几何图形记录数据信息的,QR码是常见的一种二维码.推荐使用生成QR码的php类库PHP QR Code. 例子: <?php ini_set('display_e ...
- shell字符串操作详解
shell字符串操作详解的相关资料. 1.shell变量声明的判断 表达式 含义 ${var} 变量var的值, 与$var相同 ${var-DEFAULT} 如果var没有被声明, 那么就以$DE ...
- centos yum 安装问题
yum [Errno 256] No more mirrors to try 解决方法 输入下面的命令即可解决问题: yum clean all yum makecache 导致 centos安装软件 ...