版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第13章模板与异常处理杨琦西安交通大学
计算机教学实验中心
本章目标掌握函数模板概念和使用掌握类模板概念和使用了解异常处理机制授课内容13.1模板13.2异常处理机制13.3友元13.1模板函数模板template<<模板参数表>><类型><函数名>(<参数表>) { … }类模板template<class<类型参数>>class<类名>{……};例13.1定义求两个数据最大值的函数模板#include<iostream>#include<string>usingnamespacestd;template<classT>TMax(Ta,Tb){returna>b?a:b;}intmain(){inti1=3,i2=5;doubled1=3.3,d2=5.2;stringstr1("xjtu"),str2("xian");cout<<"Typeint:"<<Max(i1,i2)<<endl;cout<<"Typedouble:"<<Max(d1,d2)<<endl;cout<<"Typestring:"<<Max(str1,str2)<<endl;return0;}函数模板的几点本卷须知〔1〕在函数模板的参数表中,至少有一个参数的类型为模板的类型参数。另外,函数的返回值的类型也可以是该类型参数。〔2〕模板中可以带有多个参数类型。例如:template<classT1,classT2,classT3>voidfunc1(T1arg1,T2arg2,T3arg3){…}〔3〕函数模板参数表中可以带有未给出的、已存在的数据类型。例如:template<classT> Tfunc2(Targ1,intarg2){…}函数模板的引入例:分别在n个元素的整型和实型数组中找出最大值。算法:动态分配数组空间分别用两个函数求int和float型数组的最大和最小值。特征:函数代码相似,仅数据类型不同在C++中,把代码相同,仅数据类型不同的多个函数,可以抽象用一个函数通过设置“类型”参数实现其功能。该函数为模板函数。#include<iostream.h>template<classT>Tmaxval(T*pa,intn){Tmax=*pa;for(intk=1;k<n;k++)if(pa[k]>max)max=pa[k];returnmax;}intmain(){int*p1,n;float*p2;cout<<“输入数据个数:”;cin>>n;p1=newint[n];if(p1==NULL)return1;cout<<“输入”<<n<<“个整数:”<<endl;for(intk=0;k<n;k++)cin>>p1[k];cout<<“最大:”<<maxval(p1,n)<<endl;p2=newfloat[n];if(p2==NULL)return2;cout<<“输入”<<n<<“个实型数:”<<endl;for(intk=0;k<n;k++)cin>>p2[k];cout<<“最大:”<<maxval(p2,n)<<endl;return0;}13.1.2类模板类是对问题空间的抽象,而类模板那么是对类的抽象,即更高层次上的抽象。与函数模板相似,程序中可以通过高度抽象首先定义一个类模板,然后通过使用不同的实参生成不同的类。类模板的定义方法为:template<class<类型参数>>class<类名>{……};例13.2定义一个通用的栈类654321栈中最大数目m_nMaxElement栈中数据数目m_nTopboolPush(T);boolPop(T&);整型、字符型例13.2定义一个通用的栈类template<classT,intn=10>classAnyStack{ T m_tStack[n];int m_nMaxElement;int m_nTop;public:AnyStack():m_nMaxElement(n),m_nTop(0){}intGetTop(){returnm_nTop;}boolPush(T);//入栈函数boolPop(T&);//出栈函数};template<classT,intn>boolAnyStack<T,n>::Push(Telem){if(m_nTop<=m_nMaxElement){m_tStack[m_nTop]=elem;m_nTop++;returntrue;}else returnfalse;}template<classT,intn>boolAnyStack<T,n>::Pop(T&elem){ if(m_nTop>0) { m_nTop--; elem=m_tStack[m_nTop]; returntrue; } else returnfalse;}例13.2定义一个通用的栈类intmain(){intn;strings1;AnyStack<int>iStack;//定义一个整数栈iStack.Push(5);iStack.Push(6);iStack.Pop(n);cout<<"第一个出栈整数="<<n<<endl;iStack.Pop(n);cout<<"第二个出栈整数="<<n<<endl;AnyStack<string>strStack;//定义一个字符串栈strStack.Push("It'sfirststring");strStack.Push("It'ssecondstring");strStack.Pop(s1);cout<<"第一个出栈字符串="<<s1<<endl;strStack.Pop(s1);cout<<"第一个出栈字符串="<<s1<<endl;return0;}13.2异常处理机制C++的异常处理使程序可以向更高的层次传递意想不到的事件,从而使程序能更好地从这些异常事件中恢复过来。下面具体介绍异常处理的语法。1.异常处理的语法①throw表达式用来检测是否产生异常,假设是,那么抛掷异常。语法如下:throw表达式;②try是一个复合语句块,它将那些有可能产生异常的语句框定在try块中,并根据异常的情况使用不同的throw表达式抛出异常。语法如下:13.2异常处理机制try{//复合语句……throw表达式1;……throw表达式2;……throw表达式n;}③紧接try块,使用catch块,将异常处理的语句放在catch块中,以便异常被传递过来时就处理它。每个catch块是一个复合语句,处理相应的异常。语法如下:13.2异常处理机制catch(异常类型说明1){......//复合语句}catch(异常类型说明2){......//复合语句}……catch(异常类型说明n){......//复合语句}如果某程序中发现了自己不能处理的异常,就可以使用throw表达式抛掷这个异常,将它抛掷给调用者。throw的操作数在表示异常类型语法上与return语句的操作数相似。13.2异常处理机制try块中的复合语句是代码的保护段。如果预料某段程序代码〔或对某个函数的调用〕有可能发生异常,就将它放在try块中。如果这段代码〔或被调用的函数〕运行时真的遇到异常的情况,其中的throw表达式就会抛掷这个异常。紧接try块的catch块复合语句是异常处理程序,“捕获”由throw表达式抛掷的异常。13.2异常处理机制2.异常处理的执行过程①控制通过正常的顺序执行到达try语句,然后执行try块的保护段。②如在保护段执行期间没有引起异常,就跳过try块后的所有catch块,继续执行紧接最后一个catch块后面的程序。例13.3异常处理机制的使用#include<iostream.h>voidtestfun(inttest){ try{ if(test)throwtest; elsethrow"itisazero";} catch(inti) {cout<<"Exceptoccurred:"<<i<<endl;} catch(constchar*s) {cout<<"Exceptoccurred:"<<s<<endl;}}intmain(){testfun(100);testfun(0);return0;}异常规格说明异常规格说明存在于函数说明中,位于参数列表之后。函数的所有潜在异常类型均随着关键字throw而插入函数说明中。如:voidSetElem(inti,intj,doubleval)throw(InvalidIndex);而传统的函数声明,如:voidSetElem(inti,intj,doubleval);可能抛出任何一种异常。而voidf(inti,floatj,doubleval)throw();不能抛出任何一种异常。好的编程习惯:对于每一个有异常抛出的函数都应当参加异常规格说明。自学内容友元:允许类外部的函数或者类具有该类私有成员的特权。友元函数友元类13.3友元函数一个类的友元函数是在该类中说明的、用关键字friend修饰的函数,该函数有权访问类中所有的成员。说明一个友元的一般形式为friend<类型><函数名>(<参数表>);例如:classPerson{ ......public:friendvoidFriFunc(Person&person);......};voidFriFunc(Person&person){ ......}一个类的友元可以是类外的任何函数,包括不属于任何类的函数和属于某个类的成员函数。13.3友元类当一个类成为另一个类的友元时,就构成了友元类。这意味着该类的每一个成员函数都是另一个类的友元函数。如:classPerson{......public:friendclassGovernment;......};程序设计举例[例13-4]定义一个求幂函数的函数模板。[例13-5]用函数模板实现顺序查找算法。[例13-6] 定义一个通用的栈类并测试。[例13-7]除0异常。[例13-8]求一元二次方程ax2+bx+c=0的根,其中系数a,b,c为实数,由键盘输入。要求使用异常机制。例13-4定义一个求幂函数的函数模板#include<iostream.h>template<classT>TPower(Ta,intexp){ Tans=a; while(--exp>0)ans*=a; returnans;}intmain(){ cout<<"3^5="<<Power(3,5)<<endl; cout<<"1.1^2="<<Power(1.1,2)<<endl; return0;}例13-5用函数模板实现顺序查找算法#include<iostream.h>template<classT>intsequentialsearch(Ta[],constT&k,intn){ inti=0; while(k!=a[i]&&i<=n-1) i++; if(i>n-1)i=-1; returni;}intmain()//测试用主函数{ inti1[]={3,2,5,0,-1,7}; doubled1[]={3.3,2.1,0.3,1.5,10.6,5.2}; char*c1="xjtu"; cout<<sequentialsearch(i1,15,6)<<endl; cout<<sequentialsearch(d1,3.3,5)<<endl; cout<<sequentialsearch(c1,'j',4)<<endl; return0;}例13-7:除数为0时的异常intmain(){doublen1,n2,result;cout<<"Inputtwonumber:”;while(cin>>n1>>n2){try{result=Div(n1,n2);cout<<n1<<"/"<<n2<<"="<<result<<endl;} catch(double){cout<<“产生异常:0作除数"<<endl;}cout<<"Inputtwonumber:”;}cout<<"Thatisok."<<endl;return0;}doubleDiv(doublea,doubleb){ if(b==0.0) throwb; returna/b;}[例13-8]求一元二次方程的根#include<iostream.h>#include<math.h>voidRoot(doublea,doubleb,doublec){ doublex1,x2,delta; delta=b*b-4*a*c; if(a==0)throw"dividebyzero"; if(delta<0)throw0; x1=(-b+sqrt(delta))/(2*a); x2=(-b-sqrt(delta))/(2*a); cout<<"x1="<<x1<<endl<<"x2="<<x2<<endl;}intmain(){doublea,b,c;cout<<"pleaseintputa,b,c=?";cin>>a>>b>>c;try{Root(a,b,c); }catch(char*){cout<<"itisnotaquadraticequation."<<endl;}catch(int){cout<<"therealrootofthisequationdoesnotexist."<<endl;}return0;}实例编程---矩阵类实现一个实数矩阵类:可以进行加、减、乘和赋值运算,并且要重载运算符“〔〕”,用来返回矩阵元素的值。同时,该类还要支持异常处理机制,能够处理可能的非法矩阵操作。算法一个Matrix对象是具有row和col列double型元素,将它们以行顺序存放在elems中。两个矩阵可以相乘的前提条件是前一个矩阵的列数等于后一个矩阵的行数,具体算法见例4-4。矩阵的加减和赋值运算是每个对应元素的加减和赋值运算,所以进行该类运算的矩阵必须维数相同。小结C++中提供了两种模板类型:函数模板、类模板。函数模板的定义方法为:template<class<类型参数>><类型><函数名>(<参数表>) { … }类模板的定义方法为template<class
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论