c++ 异常处理_第1页
c++ 异常处理_第2页
c++ 异常处理_第3页
c++ 异常处理_第4页
c++ 异常处理_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、本章主要内容l异常处理的机制异常处理的机制lC+异常处理的实现异常处理的实现l标准程序库异常的用法标准程序库异常的用法 l异常处理中的构造与析构异常处理中的构造与析构l多个异常事件的处理多个异常事件的处理 l小结小结11.1异常处理的机制异常处理的机制-n异常:程序执行时遇到的任何错误情况或意外异常:程序执行时遇到的任何错误情况或意外行为行为 n异常处理:异常处理: 异常处理就是指当程序出现这些错误后,异常处理就是指当程序出现这些错误后,给与恰当处理,为程序提供退出的安全通道给与恰当处理,为程序提供退出的安全通道 11.1异常处理的机制异常处理的机制-n异常可能性:异常可能性:代码或调用的代码

2、(如共享库)中有错误;代码或调用的代码(如共享库)中有错误; 操作系统资源不可用;操作系统资源不可用; 公共语言运行库遇到意外情况(如无法验证代公共语言运行库遇到意外情况(如无法验证代码);码); 用户的错误操作等用户的错误操作等 11.1异常处理的机制异常处理的机制 - #include#includeusing namespace std;void main()char str40;char msg=Connot open infile-hello.txt;ifstream fin(hello.txt);if(!fin)coutmsgstr;coutstrendl;fin.close();

3、return;(T1.cpp)11.1异常处理的机制异常处理的机制 - 弊端:弊端:例如函数返回例如函数返回NULL代表出现异常,但是如代表出现异常,但是如果函数确实要返回果函数确实要返回NULL这个正确的值时就会这个正确的值时就会出现混淆;出现混淆;可读性降低,将程序代码与处理异常的代码混可读性降低,将程序代码与处理异常的代码混在一起;在一起;由调用函数的程序来分析错误,这就要求客户由调用函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解程序员对库函数有很深的了解 。11.1异常处理的机制异常处理的机制 - 要求:要求:需要更加灵活、程序可读性强、降低程序员劳动需要更加灵活、程序可

4、读性强、降低程序员劳动强度的处理方式。强度的处理方式。C+ 异常处理机制:异常处理机制: 在于当遇到异常时,系统不是马上终止运行,而是在于当遇到异常时,系统不是马上终止运行,而是允许用户排除错误,继续运行程序,至少给出出错提允许用户排除错误,继续运行程序,至少给出出错提示信息。示信息。在大型复杂的软件系统中,函数之间有明显的分工和复在大型复杂的软件系统中,函数之间有明显的分工和复杂的调用关系,发现错误的函数一般不具备处理错误杂的调用关系,发现错误的函数一般不具备处理错误的能力。这时只能导致一个异常,并抛出异常,让它的能力。这时只能导致一个异常,并抛出异常,让它的调用者捕获这个异常并处理,如果调

5、用者也不能处的调用者捕获这个异常并处理,如果调用者也不能处理就传递给它的上级调用者,这样一直上传到能处理理就传递给它的上级调用者,这样一直上传到能处理为止。如果始终没有处理就上交到为止。如果始终没有处理就上交到C+运行系统,运行系统,运行系统调用运行系统调用abort函数强行终止整个程序。函数强行终止整个程序。11.1异常处理的机制异常处理的机制 - 函数f()捕获并处理异常函数h() 引发异常函数g()调用者异常传播方向调用关系11.1异常处理的机制异常处理的机制异常异常 11.2异常的实现异常的实现异常异常 C+语言中:语言中:try、throw和和catch语句就是用于实现异语句就是用于

6、实现异常处理的机制的程序子句:常处理的机制的程序子句:1. 确定要保护的代码段确定要保护的代码段 确定要保护的代码段(敏感代码)的工作由确定要保护的代码段(敏感代码)的工作由try子句来实现。如果预料某段代码可能出现异常,子句来实现。如果预料某段代码可能出现异常,就将此段代码放在就将此段代码放在try语句块中。这段代码在语句块中。这段代码在运行时真的出现了错误,就通过其中的运行时真的出现了错误,就通过其中的throw语句抛掷异常对象的类型和异常的内容。语句抛掷异常对象的类型和异常的内容。11.2异常的实现异常的实现异常异常2. 抛掷异常抛掷异常抛掷异常的工作由抛掷异常的工作由throw子句来实

7、现,在受保子句来实现,在受保护的可能产生异常的语句中进行错误检测,如护的可能产生异常的语句中进行错误检测,如有异常就通过有异常就通过throw语句抛掷异常对象的类型语句抛掷异常对象的类型和异常的内容。和异常的内容。3. 定义异常处理程序定义异常处理程序通过通过throw抛掷的异常对象和异常内容,被抛掷的异常对象和异常内容,被catch子句捕获,并处理捕获的异常对象。即子句捕获,并处理捕获的异常对象。即将出现异常后对异常的处理语句放在将出现异常后对异常的处理语句放在catch语语句块中,捕捉异常并处理,句块中,捕捉异常并处理,catch子句起到了子句起到了异常处理器的作用。异常处理器的作用。11

8、.2异常的实现异常的实现异常异常 #include#include#includeusing namespace std;void main()char str40;char msg=Connot open infile-hello.txt;ifstream fin(hello.txt);tryif(!fin) throw string(msg); 11.2异常的实现异常的实现异常异常catch(string s)coutsstr;coutstrendl;fin.close();return;(T3.CPP)11.2异常的实现异常的实现异常异常n执行过程如下:执行过程如下:n1、通过正常的控制

9、顺序执行到、通过正常的控制顺序执行到try语句,进入语句,进入try块块内执行保护段程序。内执行保护段程序。n2、在、在try语句块中,如果语句块中,如果try中没有异常,后面的中没有异常,后面的catch语句不执行,继续执行语句不执行,继续执行catch后的程序语句。后的程序语句。例中如果例中如果fin不为空(不为空(NULL),则),则try后的后的catch子句子句就不执行,继续执行就不执行,继续执行catch语句块后的程序。如有多语句块后的程序。如有多个个catch语句块时,跳到最后一个语句块时,跳到最后一个catch语句块的后语句块的后面执行。面执行。n3、在、在try语句块中,有异

10、常时,就通过语句块中,有异常时,就通过throw语句创语句创建一个异常对象,例中如果建一个异常对象,例中如果fin为空(为空(NULL),则通),则通过过throw创建一个异常对象,这里用字符串创建一个异常对象,这里用字符串msg,创,创建一个建一个string 的的s对象。对象。11.2异常的实现异常的实现异常异常n执行过程如下:执行过程如下:4、当异常被抛掷后,、当异常被抛掷后,try语句块后的语句块后的catch语句语句便依次被检查,若某个便依次被检查,若某个catch子句的异常声明子句的异常声明与被抛掷的异常类型一致,则执行该异常处理与被抛掷的异常类型一致,则执行该异常处理程序。程序。

11、n5、如果没有一个、如果没有一个catch的类型与其匹配,则的类型与其匹配,则函数函数terminate被调用,被调用,terminate函数的功函数的功能就是调用能就是调用abort()函数终止程序运行。函数终止程序运行。11.2异常的实现异常的实现异常异常/除数为零的异常处理除数为零的异常处理#include#includeusing namespace std;float Division(float x,float y)if(y=0)throw string(except of dividing zero.); return x/y;11.2异常的实现异常的实现异常异常void mai

12、n()int x1=5,y1=6;int x2=6,y2=0;int x3=7,y3=2;trycoutx1/y1=Division(x1,y1)endl;coutx2/y2=Division(x2,y2)endl;coutx3/y3=Division(x3,y3)endl;catch(string s)coutsendl;return;(T4.cpp)11.2异常的实现异常的实现异常异常n注意:注意:()()C+只处理受监控的程序的异常;只处理受监控的程序的异常;()()try语句后必需紧跟一个或多个语句后必需紧跟一个或多个catch语句,语句,目的是对发生的异常进行捕获并处理。目的是对发生

13、的异常进行捕获并处理。()()catch()括号中只能声明一个形参,当()括号中只能声明一个形参,当预定义的类型与被抛掷的异常对象类型匹配时,预定义的类型与被抛掷的异常对象类型匹配时,该该catch()便捕获了一个异常,程序执行进入其便捕获了一个异常,程序执行进入其块中执行。块中执行。11.2异常的实现异常的实现异常异常/下面的例为成员函数抛掷异常对象的例子。下面的例为成员函数抛掷异常对象的例子。#includeusing namespace std;class StudentDeptpublic: StudentDept(char *p) DepName=new charstrlen(p);

14、 strcpy(DepName,p); DepNamestrlen(p)=0; char seek(int i) /找到系名中的第找到系名中的第i个字母个字母 if(i=0&istrlen(DepName) return DepNamei; else throw 超出了系名字符个数。超出了系名字符个数。; /抛出异常对象抛出异常对象 private: char * DepName;11.2异常的实现异常的实现异常异常void main() StudentDept dep(Computer); trycoutdep.seek(10)endl; catch(char *m) coutmendl;

15、(T7.cpp)11.2异常的实现异常的实现 为了让程序员能够明确函数所抛掷的异常,可以为了让程序员能够明确函数所抛掷的异常,可以在函数的声明时列出函数可能抛掷的异常类型,在函数的声明时列出函数可能抛掷的异常类型,其形式为:其形式为:函数返回值类型函数名(含数形参列表)函数返回值类型函数名(含数形参列表)throw(异常类型列表异常类型列表);例如:例如:void fun() throw(int,string,float);抛出的异常对象的类型有抛出的异常对象的类型有int 、string、float。11.2异常的实现异常的实现当为当为throw()的形式时,此函数不抛出任何类型的形式时,此

16、函数不抛出任何类型的异常对象。的异常对象。如:如:void fun() throw();函数后面没有函数后面没有throw(异常类型列表异常类型列表)子句时,抛子句时,抛出任何类型的异常对象,即抛出的异常对象的出任何类型的异常对象,即抛出的异常对象的类型不定。类型不定。如:如:void fun();11.2异常的实现异常的实现/要求除数不小于要求除数不小于#include#includeusing namespace std;float Division(float x,float y) throw(string,float);void main()int x1=5,y1=6;int x2=6

17、,y2=1;int x3=7,y3=2;trycoutx1/y1=Division(x1,y1)endl;coutx2/y2=Division(x2,y2)endl;coutx3/y3=Division(x3,y3)endl;catch(string s)coutsendl;11.2异常的实现异常的实现catch(float s)cout除数为除数为:s,要求除数不小于要求除数不小于2。endl;return;float Division(float x,float y)if(y=0)throw string(除数为零除数为零); if(y2)throw float(y);return x/y

18、;(T5.cpp)11.3标准程序库异常的用法标准程序库异常的用法/利用标准程序库提供的异常处理来实现对内存申请操作过量,导致系统发出利用标准程序库提供的异常处理来实现对内存申请操作过量,导致系统发出bad_alloc异常的处理异常的处理:#include #include using namespace std;class BigClass public: BigClass() ; BigClass() double BigArray99999999;void main() try BigClass * p = new BigClass; 11.3标准程序库异常的用法标准程序库异常的用法 c

19、atch( bad_alloc a) const char * temp = a.what(); cout temp endl; cout Threw a bad_alloc exception endl; BigClass * q = new(nothrow) BigClass; if ( q = NULL ) cout Returned a NULL pointer endl; try BigClass * r = new BigClass3; catch( bad_alloc a) const char * temp = a.what(); cout temp endl; cout Th

20、rew a bad_alloc exception endl; (T61.cpp)11.4异常处理中的构造与析构异常处理中的构造与析构 n具有在异常抛掷前构造异常对象和自动销毁异常对象。具有在异常抛掷前构造异常对象和自动销毁异常对象。n在程序中,找到一个匹配的在程序中,找到一个匹配的catch异常处理后,如果异常处理后,如果catch子句的异常类型为一个值参数,则初始化方式子句的异常类型为一个值参数,则初始化方式是将异常对象传递给是将异常对象传递给catch的形参,此时要调用异常的形参,此时要调用异常对象的拷贝构造函数来实现。如果对象的拷贝构造函数来实现。如果catch子句的异常子句的异常声明

21、是一个引用,则使声明是一个引用,则使catch形参指针指向异常对象。形参指针指向异常对象。当当catch子句执行完成后,就意味着对应由子句执行完成后,就意味着对应由throw抛出抛出的异常对象将自动销毁,的异常对象将自动销毁,catch子句捕获异常对象时子句捕获异常对象时调用拷贝构造函数生成的对象也需要自动销毁,完成调用拷贝构造函数生成的对象也需要自动销毁,完成异常对象的析构。析构的顺序与构造的顺序相反。程异常对象的析构。析构的顺序与构造的顺序相反。程序从最后的序从最后的catch语句块后继续恢复正常执行。语句块后继续恢复正常执行。11.4异常处理中的构造与析构异常处理中的构造与析构/使用带构

22、造和析构函数的类的异常处理使用带构造和析构函数的类的异常处理#includeusing namespace std;class Exceptionpublic:Exception()cout构造构造Exception的对象的对象endl;Exception(Exception &exp)cout拷贝构造拷贝构造Exception的对象的对象endl;Exception()cout析构析构Exception的对象的对象endl;char *Show()return Exception 类异常。类异常。;11.4异常处理中的构造与析构异常处理中的构造与析构class StudentDeptpubl

23、ic: StudentDept(char *p) DepName=new charstrlen(p); strcpy(DepName,p); DepNamestrlen(p)=0; cout构造构造StudentDept的对象的对象=0&istrlen(DepName) return DepNamei; else cout要抛出要抛出Exception类异常类异常endl; throw Exception(); /抛出异常对象抛出异常对象 StudentDept() cout析构析构StudentDept的对象的对象endl; private: char * DepName;11.4异常处理中

24、的构造与析构异常处理中的构造与析构void main() tryStudentDept dep(Computer);coutdep.seek(10)endl;catch(Exception e)cout在在catch异常程序处理之中。异常程序处理之中。endl;cout捕获到捕获到Exception类异常类异常:;coute.Show()endl; catch(char *m) cout捕获到其它类的异常:捕获到其它类的异常:mendl; (T8.cpp)11.5多个异常事件的处理多个异常事件的处理/从文件中读学生信息从文件中读学生信息#include#include#includeusing namespace std;class Exceptionpublic:Exception(char *m)msg=new charstrlen(m)+1;strcpy(msg,m);msgstrlen(m)=0;Exception(Exception &exp)msg=new charstrlen(exp.msg)+1;strcpy(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论