C程序设计--对象分册(第5章).ppt_第1页
C程序设计--对象分册(第5章).ppt_第2页
C程序设计--对象分册(第5章).ppt_第3页
C程序设计--对象分册(第5章).ppt_第4页
C程序设计--对象分册(第5章).ppt_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

C/C+程序设计教程,郑秋生 主编,2019/7/11,2,第5章 异常处理及命名空间,本章学习重点掌握内容: 异常的概念、异常的产生 异常的处理机制 throw、try和catch的用法 命名空间的概念及使用,2019/7/11,3,第5章 异常处理及命名空间,5.1 异常处理 5.2 命名空间,5.1 异常处理,5.1.1 异常的概念 程序需要在各种不同环境下使用时,需要考虑在这些异常情况下程序的响应能力。 所谓异常(Exception)是程序运行过程中,由于环境变化、用户操作失误以及其它方面的原因而产生的运行时不正常的情况,它要求程序立即进行处理,否则将会引起程序错误甚至崩溃的现象。,2019/7/11,4,5.1 异常处理,5.1.2 异常处理机制 C+采用机制是,当本函数运行出现异常时,可以不在本函数处理,而是发出异常信息(抛出异常);调用者可以捕捉到这一个信息(捕获异常),根据对应的出错信息进行相应的处理(处理异常);或向更上一层调用发出异常信息(再次抛出异常)。 C+引入了3个关键字try(检查异常),throw(抛出异常)和catch(捕获异常),用于进行异常处理。首先,程序员将一组有可能引起异常的语句放在try块中,当程序执行过程中,如果遇到错误,它就通过throw语句抛出一个异常。而catch块用来捕捉异常,并进行相应的处理。,2019/7/11,5,【例5.1】抛出异常到处理异常的过程,#include using namespace std; double divide(double x1, double x2) /输入偶数,否则产生异常 if(x2=0) throw “除数为0,无法计算!“; /抛出异常 return x1/x2; / 程序其它部分 ,2019/7/11,6,int main() double x1,x2,dRet ; bool bRet = true; coutx1x2; try dRet = divide(x1,x2); /divide可能抛出异常 catch (char* message) /捕获异常 bRet =false; coutmessageendl; if(bRet) coutx1“/”x2“=”dRetendl; return 0; ,异常的处理语法,throw 表达式; 说明:throw后的表达式表示抛出异常的类型,可以是一个变量、常量或一个对象。throw语句在语法上与return语句相似。 try-catch结构描述如下: try 被检查语句 catch(异常类型声明) 异常处理语句 ,2019/7/11,7,异常语法说明-1,1. try块可以包含任何C+语句,甚至可以包含整个函数,但是try块必须包含能够抛出异常的语句。当被检测的函数出现异常时,catch块中获得异常的信息。 2. try 块和catch块作为一个整体出现,且catch必须紧跟在try块之后,中间不能插入其他语句。 3. try块可以单独出现,而无catch块,表示无论是否有异常都不进行处理。 4.一个try-catch结构中,只能有一个try块,可以有多个catch块,每个catch块的异常信息必须是不同的数据类型,以使和不同异常信息匹配。,2019/7/11,8,异常语法说明-2,6. try-catch结构可以和throw出现在同一函数中,这时throw抛出异常后,catch首先和匹配本函数的抛出的异常,如果匹配则由本函数catch捕获否则,由上一层函数处理。 7. throw可以不包含参数,用于catch捕获后再原样抛出,由上一层处理。 8. 异常信息假如没有被捕捉则异常会发生。如上述例题例5.1,没有捕获异常则0作为除数相除,引起系统崩溃。 9. 在异常处理过程中也可能存在“单个catch子句不能完全处理这个异常”的情况。那么该异常处理器在做完局部能够做的事情后,会再一次抛出这个异常,让更一层函数处理,也就是重新抛出。,2019/7/11,9,异常语法说明-3,11. throw 抛出的可以是一个常量,也可以是一个变量。关键字throw 还可以灵活地放到很多地方,只要try块中的语句能直接或间接地执行到它。 12. 如果catch中处理程序执行完毕,而无返回或终止指令,将跳过后面的catch块继续执行程序。 13. catch在比较类型匹配时并不需要完全相同。被throw抛出的异常的数据类型与catch 处理程序的参数类型进行匹配的过程, 由精确匹配和自动数据类型转换的匹配组成。,2019/7/11,10,两者类型匹配说明,catch的参数类型与抛出异常严格匹配; catch的参数类型是被抛出异常所在类的公有基类; catch的参数类型是指向基类的指针,2019/7/11,11,【例5.2】重新抛出捕捉异常的例题。,#include using namespace std; void fun2( int x) throw x; void func3(int a) try fun2(a); catch (int x) /这里有x值为a; /如果异常参数x=0则进行处理,否则继续抛出 if(x=0) cout“fun3中处理异常!“endl; else cout“重新抛出异常!“endl; throw x; /重新抛出 ,2019/7/11,12,int main() try func3(1); catch (int x) cout“处理了int类型的异常!“endl; return 0; ,【例5.3】类型匹配捕捉异常例题,#include using namespace std; void fun2( int x) throw “抛出异常“; void fun3(int a) try fun2(a); catch (int x) /这里有x值为a; /如果异常参数x=0则进行处理,否则继续抛出 cout“fun3检测到抛出异常!“endl; ,2019/7/11,13,int main() try fun3 (-1); catch (char* str) cout“主函数捕捉了异常,异常信息是:”strendl; return 0; ,谁捕捉了异常?,程序运行结果为: 主函数捕捉了异常,异常信息是:抛出异常,5. 1.3 异常函数,C+引入了异常规范(Exception Specification)。来时抛出异常函数的使用者知道抛出异常的类型 异常规范规定:随着函数声明列出该函数可能抛出的异常,并保证该函数不会抛出其它类型的异常。 C+异常规范并非强制规定,因此,没有在函数说明后附带异常说明并非语法错误。 目前有些编译器并不完全支持异常规范,,2019/7/11,14,常见附带异常说明函数说明有以下3种情况。 (1)函数返回类型 函数名(参数列表) throw(类型列表); (2)函数返回类型 函数名(参数列表) throw(); (3)函数返回类型 函数名(参数列表); 说明 在第一种情况中,函数所有可能抛出的异常类型都列在类型列表中,其中类型列表可以是一到多种数据类型,包括自定义数据类型。 第二种情况表示函数不会抛出任何类型的异常。 第三种情况就是函数的声明,它表示函数有可能抛出任何类型的异常。,2019/7/11,15,5. 1.4 标准C+库中的异常类,在标准C+库中提供了一个异常类的基类exception和它的多个派生类。用于报告C+标准库中的函数在执行期间遇到的不正常情况。这些类分别定义在C+标准库的四个头文件中, (1)头文件中定义了异常类exception和bad_exception,异常类exception是标准C+库中所有异常类的基类。 (2)头文件中定义了异常类ios_base:failure。 (3)头文件中定义了异常类bad_cast和bad_typeid,当dynamic_cast失败时将抛出该异常类对象。 (4)头文件中定义了其它所有的异常类,如logic_error 、out_of_range 、range_error、runtime_error等。,2019/7/11,16,标准C+库中提供的异常类构成了一个类继承的层次结构。除了报告标准库中的函数在执行期间遇到的不正常情况外,程序员也可以直接使用这些类编写程序,或使用这些类作为基类派生自己的异常类。 根类exception定义在头文件中,是C+标准库函数抛出的所有异常的基类。,2019/7/11,17,【例5.5】 异常综合使用实例,#include #include using namespace std; class CMyException /异常类,该类的对象作为抛出异常时传递的异常参数。 public: CMyException (string n=“none“) : name(n) /构造函数,根据参数n构造一个名字为n的异常类对象 cout“构造一个CMyException对象,名称为:“nameendl; CMyException (const CMyException,2019/7/11,18,class CTestClass /测试类,其构造函数可能抛出int型或char*型异常 public: CTestClass(int x) throw(int); void print(); private: int a; ; CTestClass: CTestClass(int x) throw(int) /本层直接处理char*类型异常,int类型异常由上层处理 try if(x=0) throw 0; if(x1000) throw “x值太大!“; a = x; catch(char* s)/ cout“处理了char*类型异常信息:“sendl; void CTestClass:print() coutaendl; ,异常综合使用实例-2,void fun1(int x) throw(CMyException, int) / 可能抛出CMyException, int类型异常,但是如果只写throw(CMyException),编译器也能编译通过 CTestClass a(x); a.print(); CMyException obj2(“obj2“); throw obj2; int main() try /抛出指针异常,需要在捕捉中删除指针, /这种情况本层函数抛出并捕捉是可以, /如果本层函数抛出,而调用者捕捉删除指针,就不是一个高质量的程序 throw new CMyException(“obj1“); catch(CMyException *e) coutGetName()endl; delete e; ,2019/7/11,19,try coutx; fun1(x); catch(int x) cout“处理了int类型的异常:“xendl; catch(char *s)/这个捕捉永远不会被处理 cout“处理了char*类型的异常:“sendl; catch(CMyException ,讨论,运行结果发现,fun1中抛出异常后,由产生一个拷贝对象,这是由于抛出对象后,产生了一个临时对象,捕捉对象采用引用方式,实际上是临时对象的引用,如果捕捉时,采用值方式,则会再增加一次拷贝。 为减少拷贝的次数,捕捉对象采用引用的方式。,2019/7/11,20,5.2 命名空间,需要程序员使用第三方提供的库时,必须保证程序中的变量不和第三方提供的库中的全局实体名字冲突,为了解决这个问题,C+引入命名空间机制。 5.2.1 命名空间的定义 定义命名空间的语法格式如下。 namespace 命名空间名 声明序列 ,2019/7/11,21,注意下面几个方面,namespace只能在全局范畴定义,但它们之间可以互相嵌套,即在命名空间定义内容定义一个新的命名空间。 可以通过多次声明和定义同一命名空间,把新的成员名称加入到已有的命名空间之中去,即使多次声明在不同的头文件中,也是同属于同一个命名空间体。 一个namespace的名字可以用另一个名字做它的别名。 可以在命名空间之外定义命名空间的成员(如函数的定义),这时成员的名字必须被命名空间限定修饰。而且如果在命名空间之外定义,则必须则命名空间之内声明。,2019/7/11,22,5.2.2 命名空间的使用,命名空间中成员的引用,需要使用命名空间的域操作符: 如果想直接使用命名空间中的某一成员,而不用命名空间的域操作符。可以采用using声明,using格式如下: using 命名空间:命名空间.:成员名称,2019/7/11,23,using声明需要注意下几点: using声明的作用域就是using所处位置的作用域,即:如全局域中是从using使用开始到文件结束,局部域内使用则其作用域是局部的。和普通变量一样,局部变量将隐藏全局变量。 using声明名字必须在该域内是唯一,不能重复声明. using 声明用于直接指定命名空间成员,也可以使用using指定整个命名空间,语法格式为: using namespace 命名空间名:命名空间名;,2019/7/11,24,例子,using namespace std; #include #include using namespace std; namespace myNameSpace1 /自定义命名空间myNameSpace1 string myStr1 = “myStr1“; /在myNameSpace1中嵌套定义命名空间myNameSpace2 namespace myNameS

温馨提示

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

评论

0/150

提交评论