命名空间与异常处理.ppt

上传人:小飞机 文档编号:5694056 上传时间:2023-08-10 格式:PPT 页数:39 大小:268.49KB
返回 下载 相关 举报
命名空间与异常处理.ppt_第1页
第1页 / 共39页
命名空间与异常处理.ppt_第2页
第2页 / 共39页
命名空间与异常处理.ppt_第3页
第3页 / 共39页
命名空间与异常处理.ppt_第4页
第4页 / 共39页
命名空间与异常处理.ppt_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《命名空间与异常处理.ppt》由会员分享,可在线阅读,更多相关《命名空间与异常处理.ppt(39页珍藏版)》请在三一办公上搜索。

1、C+程序设计,第11章命名空间与异常处理,1、命名空间2、异常处理 3、模板,主要内容,一、命名空间,定义:是一种将程序库名称封装起来的方法,它就像在各个程序库中立起一道道围墙。比如Windows中,同一目录下不能有两个相同名称的文件,但如果把这两个文件分别放在不同的目录下,就不会存在同名文件的冲突问题。例如:C:windowstest.txt 和 C:mydatatest.txt 其中前者在C:windows目录下,后者在C:mydata目录下,这些目录就相当于命名空间,它们将同名的文件隔离在不同的目录范围内,从而避免了同名文件的冲突问题。同样道理,假如当前目录是C:windows,使用该目

2、录下的test.txt不必指明目录名,但要使用C:mydata下的test.txt,就必须使用目录名C:mydata。理解这些对后面命名空间的使用非常有益。,namespace 命名空间名/有名的命名空间 namespace/无名的命名空间,命名空间的形式,在两个头文件中分别定义一个有名字的命名空间,其中各有一个类String,但它分属不同的命名空间,即分别变成了one:String()以two:String()。这样,就可以通过声明命名空间来区分不同的类或函数等等了。,【例11.1】有名的命名空间的简单定义,/two.hnamespace two class String.;,/one.hn

3、amespace onechar func(char);class String.;,namespace Outer/命名空间Outer的定义 int i;/Outer的成员i在内部定义 namespace Inner/子命名空间Inner的内部定义 void f()i+;/Inner的成员f()的内部定义,其中的i为Outer:i int i;void g()i+;/Inner的成员g()的内部定义,其中的i为Inner:i void h();/Inner的成员h()的声明/Inner定义的结尾 void f();/命名空间Outer的成员f()的声明/Outer定义的结尾void Oute

4、r:f()i-;/命名空间Outer的成员f()的外部定义void Outer:Inner:h()i-;/命名空间Inner的成员h()的外部定义,【例11.2】命名空间的成员在外部定义,【例11.3】无名命名空间的定义,namespace/注意是无名命名空间!int i;void f()/*/int main()i=0;/可直接使用无名命名空间中的成员i f();/可直接使用无名命名空间中的成员f()由于命名空间没有名字,在其它文件中自然就没法使用,它只在本文件的作用域内有效。,【例11.4】命名空间的引用,对命名空间中成员的引用,需要使用命名空间的作用域限定运算符:,/out1.cpp#i

5、nclude out.h#include int main()Outer:i=0;Outer:f();/Outer:i=-1;Outer:Inner:f();/Outer:i=0;Outer:Inner:i=0;Outer:Inner:g();/Inner:i=1;Outer:Inner:h();/Inner:i=0;std:cout Hello,World!std:endl;std:cout Outer:i=Outer:i,Inner:i=Outer:Inner:i std:endl;,命名空间的使用规则,在本例中,有一个标识符std,即标准库的意思。标准C+库(不包括标准C库)中所包含的所

6、有内容(包括符号常量、变量、结构、类和函数等)都被定义在命名空间std(standard)中。,1、对偶尔使用的命名空间成员,一般使用命名空间的作用域限定运算符(:)来直接给名称定位。2、对一个大命名空间中的经常要使用的少数几个成员,提倡使用using声明,而不应该使用using编译指令。3、对需要反复使用同一个命名空间的许多数成员时,使用using编译指令,才被认为是可取的。,如果要使用C标准程序库的任何标识符时,可以有三种方式:1)直接指定标识符 std:cout std:hex 3.4 std:endl;2)使用using关键字using std:cout;using std:endl;

7、cout std:hex 3.4 endl;3)使用using namespace std std内定义的所有标识符都有效、可见,就好像它们被声明为全局变量一样。,命名空间的使用规则,命名空间的别名,标准C+引入命名空间,主要是为了避免成员的名称冲突。如果用户都给自己的命名空间取简短的名称,那么这些(往往同是全局级的)命名空间本身,也可能发生名称冲突。如果为了避免冲突,而为命名空间取很长的名称,则使用起来就会不方便。所以C+中提供了一种为命名空间取别名的方式来解决上述两难问题。格式为:namespace 别名=命名空间名;,【例11.5】命名空间别名的使用,namespace East_Chi

8、na_JiaoTong_University/命名空间名太长 class String String(const char*);/East_China_JiaoTong_University:String s1/虽易记但不方便!=new East_China_JiaoTong_University:String();namespace ECJTU=East_China_JiaoTong_University;/取别名ECJTU:String s2=new ECJTU:String(Beijing);/使用方便,C与C+的头文件的引用方式,在C+的程序代码开头部分,我们经常看到两种写法:第一种:

9、#include 第二种:#include using namespace std;这是使用了两种包含头文件的方法。在程序中如果要使用某个函数,就必须在程序形状部分包含相应的头文件。,在C+中使用头文件的两种方法:1)C语言的方式 头文件名包含.h后缀。由于C语言没有命名空间,所以在编程时如果要用包含.h的头文件时,不必用命名空间。2)C+的方式 标准C+要求系统提供的头文件不包含后缀.h。但C+从C语言继承了很多有用的函数,且兼容C语言,为了表示它与C语言的联系与区别,C+的头文件名是在C语言的相应头文件名(不含.h)前加上c。如C中的math.h,在C+中应该为cmath,C与C+的头文件

10、的引用方式,二、异常处理,程序在运行过程中由于使用环境的变化以及用户的操作而产生的错误,称为异常。对这些错误,应用程序如果不能进行合适的处理,将会使程序变得非常脆弱,甚至不可使用。因此,对于这些可以预料的错误,在程序设计时,应编制相应的预防代码或处理代码,以便防止异常发生后造成严重后果。一个应用程序,既要保证其正确性,还应有容错能力,在C+中,提供了一种异常处理的机制与一套方法。,异常处理的基本思想,在底层发生的问题,逐级上报,直到有能力可以处理异常的那级为止。即在应用程序中,若某个函数发现了错误并引发异常,这个函数就将该异常向上级调用者传递,请求调用者捕获该异常并处理该错误。如果调用者不能处

11、理该错误,就继续向上级调用者传递,直到异常被捕获错误被处理为止。如果程序最终没有相应的代码处理该异常,那么该异常最后被C+系统所接受,C+系统就简单地终止程序运行。如下:func1()func2()func3()func4()异常处理 引发异常 所以说,C+异常处理的目的,是在异常发生时,尽可能地减少破坏,周密地处理善后,而不去影响程序其他部分的运行。,异常处理的过程,把可能会产生异常的语句或语句块放在try语句块中。程序尝试运行这些语句,一旦它们在运行中产生了异常,那么程序不会被终止,而是转入异常处理程序,根据我们的意愿继续运行下去。,1)定义异常(try语句),try,2)抓住异常(cat

12、ch语句),将异常处理的语句放在catch语句块中,以便异常被传递来时处理。通常,异常处理是放在try语句块后的由若干个catch语句组成的程序块中,且每个try语句后面必须至少有一个catch语句。,异常处理的过程,catch(异常类型声明1)catch(异常类型声明2)catch(异常类型声明n)异常处理语句块n,如果在try语句块中发现了异常,且抛出了该异常,则这个异常就可以被某个catch语句所捕获并处理,捕获和处理的条件是被抛出的异常类型与catch语句的异常类型相匹配。由于C+使用数据类型来区分不同的异常,因此在判断异常时,throw语句中的表达式的值就没有实际意义,而表达式的类型

13、就特别重要。,异常处理的过程,3)抛出异常(throw语句),C+中的异常是通过throw语句来抛出的。它检测是否产生异常,若是,则抛出异常。,throw 表达式;,【例11.6】异常处理的简单应用,#include using namespace std;void init(int*array,int size);int main()int*p=new int10*1024*1024;int*q=new int10*1024*1024;system(pause);try init(p,10*1024*1024);init(q,10*1024*1024);,catch(.)/代表所有类型 co

14、ut程序产生异常!endl;cout准备释放内存.endl;delete q;return 1;cout准备释放内存.endl;delete p;delete q;return 0;,【例11.6】异常处理的简单应用,程序运行结果:请按任意键继续.程序产生异常!准备释放内存.功能分析:程序没有崩溃,并且及时提示发生了错误,且“准备释放内存.也出现了,说明堆内存q肯定被安全释放了。我们对异常的处理目的也达到了。,从上述程序看出,异常处理的执行过程:(1)按正常的顺序执行到try语句,然后执行try语句块内的程序段。(2)若在try语句块执行期间没有发生异常,则catch语句块不被执行。(3)若在

15、try语句块执行期间或在该语句块直接或间接调用的任何函数中发生了异常,并将异常抛出,则该异常将沿调用链上传,直到找到与该异常类型相匹配的catch语句块来处理异常。异常处理后,执行所有catch语句块的后续程序。(4)如果未找到与该异常类型相匹配的catch语句块,则由C+终止程序的运行。,【例11.6】异常处理的简单应用,补充:,(1)C+只处理放在try语句块内受监控的过程的异常。(2)在try语句块之后必须紧跟一个或多个catch语句块,以便对发生的异常进行处理。在try语句块出现之前,不能出现catch语句块。(3)catch语句的括号中只能有一个形参(可选),而形参的数据类型不能缺省

16、必须保留,因为捕获是利用数据类型的匹配实现的。(4)抛出异常与处理异常可以放在不同的函数中。(5)catch()语句可以捕获全部异常,因此,若使用这个语句,应将它放置在所有的catch语句之后。(6)为增强程序可读性,C+允许在函数的声明中注明函数可能抛弃的异常类型。语法格式:返回值类型 函数名(形参列表)throw(异常类型1,异常类2,),三、模板,模板是C+中的一个重要特性,使程序员能够快速建立具有类型安全的类库集合和函数集合,有利于在中型软件的开发。而根据使用的方式不同,又分为函数模板(function template)与类模板(class template)两种。一般来说,如果一个

17、程序的功能是对某种特定的数据类型进行处理,则将所处理的数据类型说明为参数,就可把这个程序改写为模板,模板可以让程序对任何其它数据类型进行同样方式的处理。因此模板是实现代码复用的一种工具,它可以实现类型参数化,把类型定义为参数,实现代码的真正复用。,函数模板和模板函数,函数模板首先是模板而非函数,它是各相似函数的抽象,当然具有函数的形式。模板函数则是由模板实例化后产生的具体函数。这好比工厂要生产一个茶杯,产生要根据茶杯的大致要求制造出一个模具(函数模板),之后用该模具再去批量生产茶杯(模板函数)一样。,函数模板的声明形式为:template(参数表)函数体 其中,template是定义模板函数的

18、关键字;typename是声明数据类型参数标识符的关键字,用以说明它后面的标识符是数据类型标识符(注:typename是新引入的关键字,此前一直用class,有些老版本的编译器可能不识别typename,此时宜改成class)。这样,在以后定义的这个函数中,凡希望根据实参数据类型来确定数据类型的变量,都可以用数据类型参数标识符来说明,从而使这个变量可以适应不同的数据类型。,函数模板的声明,【例11.7】简单函数模板的应用,#include using namespace std;templateT sum(T x,T y)return x+y;int main()int ia=4,ib=5,i

19、sum;float fa=4.1,fb=5.5,fsum;double da=4.12345,db=5.12345,dsum;,isum=sum(ia,ib);fsum=sum(fa,fb);dsum=sum(da,db);coutint_sum=isumendl;coutfloat_sum=fsumendl;coutdouble_sum=dsumendl;return 0;,运行结果:int_sum=9 float_sum=9.6 double_sum=9.2469,【例11.7】简单函数模板的应用,功能分析:在调用sum函数时编译器将根据数据参数的类型依照函数模板生成一个重载函数,再调用它

20、。比如:isum=sum(ia,ib);其中ia、ib是int型,函数模板会把“虚拟参数T用int代替,从而生成一个具体的模板函数int sum(int x,int y)(即由模板生成的函数):int sum(int x,int y)return x+y;程序再调用此函数得到结果为9,赋值给isum。,函数模板小结:,函数模板只是声明了一个函数的描述即模板,不是一个可以直接执行的函数,只有根据实际情况用实参的数据类型代替类型参数标识符之后,才能产生真正的函数。使用中应注意的几个问题:(1)函数模板允许使用多个类型参数,格式为:template(参数表)函数体,函数模板小结:,(2)在templ

21、ate语句与函数模板定义语句之间不允许有别的语句。templateint x;/这样声明是错误的!T min(T x,T y)函数体(3)模板函数类似于重载函数,但两者有很大不:函数重载时,每个函数体内可以执行不同的操作,但同一个函数模板实例化后的模板函数都必须执行相同的操作。,类模板与模板类,数据的类型各种各样,为了能让类适应各种类型,此时设计类时也可以象函数模板一样,定义一个与具体类型无关的类,这就是类模板。类模板可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数或返回值可以取任意的数据类型。类模板不是一个具体的类,是类的抽象类型,代表一族类,是这一族类的统一模式,类模板是一

22、个类型参数化的样板,它是一组模板类的集合,模板类是某个类模板的实例,使用某种类型来替换某个类模板的模板参数可生成该类的一个模板类。,template class 类名 类体;其中,template是声明类模板的关键字;数据类型参数标识符是类模板中参数化的类型名,当实例化类模板时,它将由一个具体的类型来代替。同样,定义类模板时,可以声明多个类型参数标识符,各标识符之间用逗号分开。,类模板的形式,类定义中,凡要采用标准数据类型的数据成员、成员函数的参数或返回类型的前面都要加上类型标识符。如果类中的成员函数要在类的声明之外定义,则它必须是模板函数。形式为:template 参数标识符 类名函数名(标

23、识符 形参1,标识符 形参n)函数体,类模板的形式,定义类模板时应注意如下几点:(1)定义类模板时使用关键字template。(2)定义类模板时至少要确定一个模板参数,多个模板参数用逗号分隔。(3)类模板的成员函数可以是函数模板。在类体外定义函数模板时,应在模板名前用类模板名限定()来表示该函数模板的所属。,类模板的形式,【例11.8】类模板的应用,#includeconst int size=10;template/定义类模板class stack T stksize;int t;public:stack()t=0;int push(T ch);/类模板的成员函数声明 T pop();,【例

24、11.8】类模板的应用,/当类模板中的成员函数在外部定义时,一定要加上下面这行!templateint stack:push(T ob)/类模板的成员函数的外部实现 if(t=size)coutstack is full!endl;return 0;stkt=ob;t+;return 1;,【例11.8】类模板的应用,template/一定不能少了此行T stack:pop()if(t=0)coutstack is empty!endl;return 0;t-;return stkt;,【例11.8】类模板的应用,int main()stackcs1,cs2;/注意要指定具体的类型,此处为ch

25、arint i;cs1.push(a);cs2.push(x);/此时自动生成处理char的模板类,cs1.push(b);cs2.push(y);/并调用对char的压栈操作cs1.push(c);cs2.push(z);for(i=0;iis1,is2;/指定为int型is1.push(1);is2.push(2);/自动生成处理int的模板类,is1.push(3);is2.push(4);/并调用对int的压栈操作is1.push(5);is2.push(6);,【例11.8】类模板的应用,for(i=0;i3;i+)coutpop is1:is1.pop()endl;for(i=0;i3;i+)coutpop is2:is2.pop()endl;return 0;,程序运行结果:pop cs1:cpop cs1:bpop cs1:apop cs2:zpop cs2:ypop cs2:x,pop is1:5pop is1:3pop is1:1pop is2:6pop is2:4pop is2:2,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号