2_第12章 01异常处理

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

virtual void PrintError(); }; void OutOfMemory::PrintError() { cout<<"Out of Memory!"<<endl; } class RangeError:public Exception { public: RangeError(unsigned number){BadNum=number;} ~RangeError(){}
进入主函数
在try模块中,调用子函数
在子函数中触发CException类异常
在catch模块中,捕获到CException类型异 常:CException 类中的异常。 回到主函数,异常已被处理。
例 : 设 计 一 个 异 常 Exception 抽 象 类 , 在 此 基 础 上 派 生 一 个 OutOfMemory类响应内存不足,一个RangeError类响应输入的 数不在指定的范围内,实现并测试这几个类。 #include <iostream.h> class Exception { public: Exception(){} virtual ~Exception(){} virtual void PrintError()=0; }; class OutOfMemory:public Exception { public: OutOfMemory(){} ~OutOfMemory(){}
异常处理的实现
C++语言异常处理机制的基本思想是将异常的检测与 处理分离。当在一个函数体中检测到异常条件存在, 但无法确定相应的处理方法时,将引发一个异常,并 由函数的直接或间接调用检测并处理这个异常。这一 基本思想用3个保留字实现:throw、try和catch。其 作用是:
(1)try:标识程序中异常语句块的开始。 (2)throw:用来创建用户自定义类型的异常错误 (3)catch:标识异常错误处理模块的开始。
19

例11-3:定义一个异常类CException,有成员函数Reason()用 来显示异常的类型,定义函数fun()触发异常,在主函数的try模块 中调用fun(),在catch模块中捕获异常,观察程序的执行过程。 #include <iostream.h> class CException { public: CException(){} ~CException(){} const char *Reason() const {return "CException 类中 的异常。";} }; void fun() {
3
异常处理的基本思想
调用者 函数f()捕获并处理异常 调用关系 异常传播方向
函数g()
函数h()引发异常
4
异常处理的基本思想
异常的基本思想是:
实际的资源分配通常在程序的低层进行,如上图中的 h()。
当操作失败、无法分配内存或无法打开一个文件时, 在逻辑上如何进行处理通常在程序的高层,如上图中 的f(),中间还可能有与用户的对话。 异常为从分配资源的代码转向处理错误状态的代码提 供了一种表达方式。如果还存在中间层次的函数,如 上图中的g(),则为它们释放所分配的内存提供了机会 5 ,但这并不包括传递错误状态信息的代码。
cout<<"在子函数中触发CException类异常"<<endl; throw CException(); }
void main() { cout<<"进入主函数"<<endl; try { cout<<"在try模块中,调用子函数"<<endl; fun(); } catch(CException E) {
cout<<"在catch模块中,捕获到CException类型异常 :"; cout<<E.Reason()<<endl; }
catch(char *str)
{ cout<<"捕获到其他类型异常:"<<str<<endl; } cout<<"回到主函数,异常已被处理。"<<endl;
}
程序的运行结果为:
unsigned int *fun2() { unsigned int *n=new unsigned int; if(n==0) throw OutOfMemory(); return n; } void fun3(unsigned int *p) { long Number; cout<<"Enter an integer(0~999):"; cin>>Number;
百度文库
range.You
used
int main() { try {fun1();} catch(Exception& theException) { theException.PrintError(); } return 0; } void fun1() { unsigned int *p=fun2(); fun3(p); cout<<"The number is:"<<*p<<endl; delete p; }
异常处理的语法
在C++程序中,任何需要检测异常的语句(包 括函数调用)都必须在try语句块中执行,异 常必须由紧跟在try语句后面的catch语句来 捕获并处理。因而,try与catch总是结合使 用。throw、try和catch语句的一般语法如 下: throw <表达式>; try { //try语句块 }
7
异常处理的语法
catch(类型1 参数1) { //针对类型1的异常处理 } catch (类型2 参数2) { //针对类型2的异常处理 } … catch (类型n 参数n) { //针对类型n的异常处理 }
8
异常处理的实现
try子句后的复合语句是代码的保护段。如果预料某段 程序代码(或对某个函数的调用)有可能发生异常, 就将它放在try子句之后。如果这段代码(或被调函数 )运行时真的遇到异常情况,其中的throw表达式就 会抛掷这个异常。
2
异常处理概述
程序可能按编程者的意愿终止,也可能因为程序中 发生了错误而终止。 程序的错误有两种,一种是编译错误,即语法错误。 如果使用了错误的语法、函数、结构和类,程序就无 法生成运行代码。另一种是在运行时发生的错误,它 分为不可预料的逻辑错误和可以预料的运行异常。 异常处理机制是用于管理程序运行期间错误的一种 结构化方法。所谓结构化是指程序的控制不会由于产 生异常而随意跳转。异常处理机制将程序中的正常处 理代码与异常处理代码显式区别开来,提高了程序的 可读性。
cout<<"Createing a Demo object."<<endl;
} ~Demo() //析构函数
{
cout<<"Deleting Demo object."<<endl; }
};
void Excp() { Demo A; cout<<endl; throw Ex(); } //创建成一个异常 //定义一个对象 cout<<"Excp function throwing an exception!";
catch子句后的复合语句是异常处理程序,“捕获” (处理)由throw表达式抛掷的异常。异常类型说明 部分指明该子句处理的异常的类型,它与函数的形参 是类似的,可以是某个类型的值,也可以是引用。
9
异常处理的例子
例:异常处理示例程序。 #include<iostream.h> void main() { char* ptr; try //异常模块 { if((ptr=new char[64*1024])==NULL) throw "Not Enough Memory!"; } catch(char* str) //异常错误处理模块 { //…… 错误处理代码 cout<<"Exception:"<<str<<endl; } }
异常处理代码的执行
(4)如果匹配的处理器未找到,则函数 terminate 将 被 自 动 调 用 , 而 函 数 terminate的默认功能是调用abort终止 程序。
(5)如果找到了一个匹配的catch处理程 序,且它通过值进行捕获,则其形参通过拷 贝异常对象进行初始化。
12
例:阅读下列程序,写出运行结果。 #include<iostream.h> void Excp(); class Ex { public: Ex(){}; ~Ex(){}; }; class Demo { public: Demo() //构造函数 {
10
异常处理代码的执行
异常处理的执行过程如下: (1)控制通过正常的顺序执行到达try语句,然 后执行try块内的保护段。 (2)如果在保护段执行期间没有引起异常,那么 跟在try块后的catch子句就不执行,程序从 异常被抛掷的try块后跟随的最后一个catch 子句后面的语句继续执行下去。 (3)如果在保护段执行期间或在保护段调用的任 何函数中(直接或间接的调用)有异常被抛掷 ,则从通过throw运算数创建的对象中创建一 个异常对象(这隐含指可能包含一个拷贝构造 11 函数)。
long
virtual void PrintError(); virtual unsigned long GetNumber(){return BadNum;} virtual void SetNumber(unsigned long number){BadNum=number;} private: unsigned long BadNum; }; void RangeError::PrintError() { cout<<"Number out of "<<GetNumber()<<"!"<<endl; } void fun1(); unsigned int *fun2(); void fun3(unsigned int *);
void main() { try { cout<<"Now call Excp function."<<endl; Excp(); } catch(Ex a) //捕捉Ex类异常 { cout<<"An Ex exception occurred."<<endl; } catch(...)
{
cout<<"Some other exception occurred."; cout<<endl; } }
17



异常接口的声明
void fun() throw(A,B,C,D); 只能抛出 A/B/C/D及其子类型的异常 void fun(); 可以抛出任何异常 void fun() throw();
不抛出任何异常
18
异常处理中的构造与析构
C++异常处理的真正能力,析构函数中具有自动析构内中 对象的能力 异常处理传递的对象 传值 传引用
面向对象程序设计(下) 课程讲义 —— C++
任课班级:116091-2
任课教师:花卫华
所在院系:信息工程学院遥感系 任课时间:2010年3月- 2010年7月
20009-3-24
1
课程大纲
1、异常处理的基本思想 2、异常处理的实现 3、异常处理中的构造与析构
4、标准程序库异常处理
(1)try分程序必须出现在前,catch紧跟出现在后。catch之 后的圆括号中必须含有数据类型,捕获是利用数据类型匹配实现 的。 (2)如果程序内有多个异常错误处理模块,则当异常错误发生时 ,系统自动查找与该异常错误类型相匹配的catch模块,查找次 序为catch出现的次序。 (3)如果异常错误类型为C++的类,并且该类有其基类,则应 该将派生类的错误处理程序放在前面,基类的错误处理程序放在 后面。 (4)如果一个异常错误发生后,系统找不到一个与该错误类型相 匹配的异常错误处理模块,则调用预定义的运行时刻终止函数, 默认情况下是abort。
此程序的运行结果为: Now call Excp function. Creating a Demo object. Excp function throwing an exception! Deleting Demo object. An Ex exception occurred.
异常处理的机制
相关文档
最新文档