第5章 异常处理
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2013-9-30
12
【例5.2】局部域声明的变量不能被局部域外引用例题。
#include <iostream.h> void main() { try { throw ("出现异常!"); } catch (char* message) { int y = 1; cout<<"异常信息:"<<message<<endl; } cout<<y<<endl; }
}
}
2013-9-30 19
5.2.7异常规范
异常规范规定:随着函数声明列出该函数可能抛出的异常, 并保证该函数不会抛出其它类型的异常。常见附带异常说明 的函数说明有以下3种情况。 (1)函数返回类型 函数名(参数列表)throw(类型列表); (2)函数返回类型 函数名(参数列表) throw(); (3)函数返回类型 函数名(参数列表); 第一种情况,函数列出所有可能抛出的异常类型;第二种情 况表示函数不会抛出任何类型的异常?;第三种情况表示函 数可能抛出任何类型的异常。 异常规范并非强制规定,因此,没有在函数说明后附带异常 说明并非语法错误。
结构化的异常处理:
2013-9-30
5
5.2 异常处理机制
C++的异常处理的基本思想是将异常的检测 与处理分离。 抛出异常
如果程序发生异常情况,而在当前的上下文环境中获 取不到处理这个异常的足够信息,程序将创建一个 包含出错信息的对象并将该对象抛出当前上下文环 境,将错误信息发送到更大的上下文环境中,这个 过程称为抛出(throw)异常。
2013-9-30
25
5.5.1 传值方式传递异常对象
按传值方式传递异常对象时,被抛出的异常都是局部变量,而 且是临时的局部变量。也就是说,每当在throw语句抛出一个异 常对象时,不管构造的对象是什么性质的变量,此时它都会复 制一份临时局部变量。
2013-9-30
26
【例5.10】按传值方式传递异常对象例题
2013-9-30 16
补充:编写异常处理代码的规则-3
catch在比较类型匹配时并不需要完全相同。 被throw抛出的异常的数据类型与catch 处理 程序的参数类型进行匹配的过程, 由精确匹配 和自动数据类型转换的匹配组成。
在下列情况视为两者类型匹配: 型与抛出异常严格匹配、
catch的参数类
5.2.1 基本概念
2013-9-30
6
5.2.1 基本概念
捕捉异常
对于一个抛出的异常,如果某一个模块能够(或想要) 处理这个异常,它就可以获得程序的控制权处理该异 常,这个过程称为捕捉(catch)异常。
处理异常
当某个catch块捕捉到异常后,它就根据事先制定的策 略对异常进行处理,这就是处理异常。在C++中,只 有catch块能够捕获异常并进行处理,因此catch块又称 为异常处理器。 C++的异常处理建立在三个关键字基础之上:
第5章 异常处理
第5章 异常处理
本章学习重点掌握内容: 异常的概念、异常的产生 异常的处理机制 throw、try和catch的用法 捕捉所有的异常 异常信号的传递方式 标准C++库的异常类
2013-9-30
2
第5章 异常处理
5.1 异常的概念 5.2 异常处理机制 5.3 没有被捕捉的异常 5.4 catch(...)使用 5.5 用类的对象传递异常 5.6 标准C++库中的异常类
2013-9-30
13
5.2.5 异常处理
C++的异常处理:
根据实际情况进行处理。
2013-9-30
14
补充:编写异常处理代码的规则-1
源自文库
可以有数量不限的catch处理程序出现在try块 之后,在try 块出现之前不能出现 catch块 在关键字catch之后的圆括号内应包括数据和 类型声明。捕获是根据throw exception 语 句的异常类型与之匹配来实现的,它与一般函 数的作用相似。 如果抛出一个异常,而在通往抛出函数的调用 链中找不到与之匹配的catch处理程序,运行 将以调用系统 terminate() 函数终止。
2013-9-30
9
5.2.3 try块
try块的语法格式如下: try { 复合语句 } try块必须包围能够抛出异常的语句。它提示编译器到 那里查找异常处理器,没有跟在try块后的catch块是没 有用的。 try块可以包含任何C++语句,甚至包含整个函数。
2013-9-30
10
5.2.4 catch块
2013-9-30
20
【例5.6】异常规范的处理例题
void func5(int x) throw(int, char*) {//x等于0抛出int型异常,x小于0抛出char*型异常,x大于0 //什么也不做 if(x==0) throw 0; if(x<0) throw "error"; } void func6() throw() { //本函数完成10个指令周期的延时,不抛出任何异常 int i = 0; while(i<10) i++; }
2013-9-30
8
5.2.2 throw语句
抛出异常的语法格式如下: throw 表达式 表达式表示异常的信息,可以是一个变量或一个对象。throw语 句在语法上与return语句相似。如。 throw 1; throw ( “出现异常”); 异常抛出后,程序的控制权就从异常抛出的地方交出,由编译器 寻找匹配的异常处理器进行相应的处理。
2013-9-30
4
问题:出现异常怎么处理
不做任何处理 直接退出程序:
用 exit (n) 或 return (n)的运行期错误处理机制, 具有“一个入口,多个出口”的特点。 积极的运行期问题处理机制。当异常出现后,可按 “警告—忽略”、“对话—补救”或安全退出等模 式,使程序可以在对运行条件出适当安排或改善后 继续下去 问题:怎么捕捉异常
2013-9-30
15
补充:编写异常处理代码的规则-2
如果catch中处理程序执行完毕,而无返回或 终止指令,将跳过后面的catch块继续执行程 序。 如果throw语句没有被执行,那么catch块将 被忽略。 在实际运用中,throw执行前一定有一个条件 判断。 throw 抛出的可以是一个常量,也可以是一个 变量。关键字throw 还可以灵活地放到很多地 方,只要try块中的语句能直接或间接地执行 到它。
catch块的语法格式如下。 catch(异常类型声明) { 异常处理语句 } ……
2013-9-30
11
5.2.4 catch块
catch 后括号中的异常类型声明可以是一个类型或一个 对象声明,后边一对“{}”括住的是一组复合语句。一 个catch块相当于一个以类型为单一参数的函数。 catch块必须直接放在try块之后。catch语句与switch语 句不同,它不需要在每个case语句后加入break用以中 断后面程序的执行。 一个catch 块引入一个局部域,在catch块内声明的变 量不能在catch 块外引用。
2013-9-30 24
5.5 用类的对象传递异常
异常信息传递是指将throw语句抛出的异常参数传递到catch块中。 但在实际应用中,由于抛出异常信息的需要,经常使用类的对象 传递异常。使用对象传递异常还有以下2个好处:
(1)在C++中,很好地实现了RTTI(Run-Time Type Information)技术,使用对象传递异常,可以很好地完成异常对 象的类型匹配。 (2)在C++中,很好地实现了对象的构造、销毁、转存复制等技 术,可以很好的实现异常信息的传递、修改和销毁等。 同函数参数传递方式一样,异常参数的传递有3种方式:传值方式、 引用方式和指针方式
catch的参数类型是被抛出异常所在类的公有基类、 catch的参数类型是指向派生类的指针
2013-9-30
17
5.2.6 重新抛出
在异常处理过程中也可能存在“单个catch子句不能 完全处理这个异常”的情况。那么该异常处理器在 做完局部能够做的事情后,可以再一次抛出,让函 数调用链中更上级的函数来处理,这个过程称作重 新抛出(rethrow) 重新抛出的throw之后可以不带参数。如果不带参数 则抛出的参数是上一级throw的参数
2013-9-30 21
5.2.7异常规范
有时,函数可能抛出没有列入异常规范的异常,出现 这种情况时,系统分两种情况进行处理。 (1)在函数内部(包括抛出异常的函数以及调用该函数 的函数链中的任意函数)捕捉到了这个异常,并进行 了相应的处理,则程序可以继续执行。。 (2)异常被抛到函数外部,这时,系统会调用C++标 准库中定义的函数unexpected(),unexpected()的缺省 行为是调用terminate(),终止程序的运行。当然,在 C++中,可以改变unexpected()的缺省行为。 必须指出VC++6.0不支持异常规范,编程可以包括异常 规范,实际什么也未做 。
2013-9-30 23
【例5.9】使用catch(...)语句的异常处理例题
func5(x); #include <iostream.h> } void func5(int x) throw(int) catch(...) { { cout<<“处理了所有类型的异常! if(x==0) throw 0; if(x<0) throw "error"; "<<endl; } } cout<<"程序结束!"<<endl; void main() } { try { int x = 0; cout<<"请输入一个int类型数据:"; cin>>x;
5.7 综合应用实例
2013-9-30
3
5.1 异常的概念
5.1.1 异常的概念 程序运行过程中,由于环境变化、用户操作失误以及其 它方面的原因而产生的运行时不正常的情况,它要求程 序立即进行处理,否则将会引起程序错误甚至崩溃的现 象。 常见的异常有:空闲内存耗尽、请求打开不存在的文件、 被0除、打印机未打开、数组越界访问等。
2013-9-30
18
【例5.4】重新抛出捕捉的异常例题。
void main() { try { func3 (1); } catch (int x) { cout<<“处理了int类型的异常! "<<endl; } }
#include <iostream.h> void func3(int x) { try { throw x; } catch (int x) { if(x<=0) {//对异常的处理 } else {cout<<"重新抛出异常!"<<endl; throw;}
try 、catch和throw。
7
2013-9-30
5.2.1 基本概念
C++的异常处理机制 C++的异常处理机制就是将抛出异常与捕捉异常、处 理异常分离开来。 抛出异常的模块并不负责异常的处理,它只是报告某 个地方存在错误,这个报告可以帮助异常处理器解决 这个错误。 异常处理器则根据抛出异常模块的报告来处理异常, 如果没有模块抛出异常,就不会有异常的处理。
#include<string> #include<iostream> using namespace std; class CMyException { public: CMyException (string n="none") : name(n) { cout<<“构造一个CMyException对象,名称为:" <<name<<endl; } CMyException (const CMyException& e) {name = e.name; cout<<"拷贝一个CMyException对象,名称为:" <<name<< endl; }
2013-9-30
22
5.4 catch(...)使用
就像switch语句中,在case语句不能罗列所有可能的情 况下,使用default语句处理其它所有情况一样。 C++在 异常处理中提供了一个能捕捉所有异常的catch块。 catch块的语法格式如下: catch(…) { 异常处理语句 } 其中,列表中的“…”表示可捕获所有的异常,但使用省 略号就不可能有参数,也不可能知道所接受到的异常为 何种类型。其它部分和普通catch块完全一样。