数据结构实验课:C++模板_第1页
数据结构实验课:C++模板_第2页
数据结构实验课:C++模板_第3页
数据结构实验课:C++模板_第4页
数据结构实验课:C++模板_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

第3讲C++模板模板的概念函数模板类模板

模板的概念所谓模板是一种使用无类型参数来产生一系列函数或类的机制,是C++的一个重要特性。它的实现,方便了更大规模的软件开发。模板是以一种完全通用的方法来设计函数或类而不必预先说明将被使用的每个对象的类型。通过模板可以产生类或函数的集合,使它们操作不同的数据类型,从而避免需要为每一种数据类型产生一个单独的类或函数。

例如,设计一个求两参数最大值的函数,不使用模板时,需要定义四个函数:intmax(inta,intb){return(a>b)?a:b;}longmax(longa,longb){return(a>b)?a:b;}doublemax(doublea,doubleb){return(a>b)?a:b;}charmax(chara,charb){return(a>b)?a:b;}若使用模板,则只定义一个函数:Template<classtype>typemax(typea,typeb){return(a>b)?a:b;}

函数模板1函数模板说明2使用函数模板3重载模板函数返回首页1函数模板说明函数模板的一般说明形式如下:template<模板形参表><返回值类型><函数名>(模板函数形参表){ //函数定义体}其中,<模板形参表>可以包含基本数据类型,也可以包含类类型。类型形参需要加前缀class。如果类型形参多于一个,则每个类型形参都要使用class。<模板函数形参表>中的参数必须是惟一的,而且在<函数定义体>中至少出现一次。2使用函数模板函数模板只是说明,不能直接执行,需要实例化为模板函数后才能执行。当编译系统发现有一个函数调用:<函数名>(<实参表>);时,将根据<实参表>中的类型生成一个重载函数即模板函数。该模板函数的定义体与函数模板的函数定义体相同,而<形参表>的类型则以<实参表>的实际类型为依据。例1:编写一个对具有n个元素的数组a[]求最小值的程序,要求将求最小值的函数设计成函数模板。

#include<iostream.h>template<classT>Tmin(Ta[],intn){ inti; Tminv=a[0]; for(i=1;i<n;i++) if(minv>a[i]) minv=a[i]; returnminv;}voidmain(){inta[]={1,3,0,2,7,6,4,5,2}; doubleb[]={1.2,-3.4,6.8,9.8}; cout<<"a数组的最小值为:"<<min(a,9)<<endl; cout<<"b数组的最小值为:"<<min(b,4)<<endl;}此程序的运行结果为:a数组的最小值为:0b数组的最小值为:-3.42024/10/29函数模板与模板函数的关系模板函数max(int

x,inty)函数模板max(Tx,Ty)模板函数max(doublex,doubley)模板函数max(Xx,Xy)实例化实例化实例化就像类和对象的关系一样,函数模板将具有相同正文的一类函数抽象出来,可以适应任意类型T。2024/10/210参数为类对象引起的问题对于上述的max函数模板,如果参与比较的是两个类对象(如Complex类的对象),该怎么办?

Complexc1,c2,c3;

c3=max(c1,c2);那么编译器将不能明白“>”运算符作用在类类型上是什么意思。在这种情况下,为了避免这个问题,必须为参与运算的类类型重载“>”运算符。2024/10/211另一个问题请思考下面情况:

voidFunc(intnum,charch){ inta=max(num,ch); intb=max(ch,num); }此时为函数模板提供了两个不同的类型(int和char),编译器无法按模板的规则实例化出那样的函数。但是int和char直接的隐式类型转换是很普遍的。解决办法:C++允许一个函数模板可以使用多个模板参数或者重载一个函数模板。3

重载模板函数例2:给出以下程序的运行结果。

#include<iostream.h>#include<string.h>template<classtype>typemax(typea,typeb){ return(a>b)?a:b;};char*max(char*a,char*b){ return(strcmp(a,b)>0?a:b);};voidmain(){ cout<<"max(\"afternoon\",\"night\")is:"<<max("afternoon","night")<<endl;}此程序的运行结果为:max("afternoon","night")is:afternoon2024/10/213例子:使用多个模板参数template<classT,classD>Tmax(Tx,Dy){ return(x>y)?x:y;}voidmain(){

inta=9; charb=34;

int

rr=max(a,b);}2024/10/214例子:重载一个函数模板template<classT>Tmax(Tx,Ty){ return(x>y)?x:y;}intmax(intx,inty){ return(x>y)?x:y;}voidmain(){ intnum=1; charch=2; max(num,num);//调用max(int,int) max(ch,ch);//调用max(T,T) max(num,ch);//调用max(int,int) max(ch,num);//调用max(int,int)}

类模板1类模板说明2使用类模板3类模板的友元4标准类模板类库1

类模板说明类模板说明的一般形式是:template<类型形参表>class<类名>{ //类说明体};template<类型形参表><返回类型><类名><类型名表>::<成员函数1>(形参表){ //成员函数定义体}template<类型形参表><返回类型><类名><类型名表>::<成员函数2>(形参表){ //成员函数定义体}…template<类型形参表><返回类型><类名><类型名表>::<成员函数n>(形参表){ //成员函数定义体}例如,下面说明一个具有两个参数的模板类。

template<classT,classS>classNode{ Node<T,S>*previous,*next; T*T_data; S*S_data;public: Node(Node<T,S>*,Node<T,S>*,T*,S*); ~Node();}template<classT,classS>Node<T,S>::Node(Node<T,S>*p,Node<T,S>*q,T*t,S*s){ previous=p;next=q;T_data=t;S_data=s;}template<classT,classS>Node<T,S>::~Node(){deleteT_data;deleteS_data;}2

使用类模板与函数模板一样,类模板不能直接使用,必须先实例化为相应的模板类,定义该模板类的对象后才能使用。建立类模板之后,可用下列方式创建类模板的实例:<类名><类型实参表><对象>;其中,<类型实参表>应与该类模板中的<类型形参表>匹配。<类型实参表>是模板类(templateclass),<对象>是定义该模板类的一个对象。例4:给出以下程序的运行结果。#include<iostream.h>template<classtype,inti>classDemoClass//定义一个类模板{ typearray[i];public: DemoClass(); ~DemoClass(); intset(typea,intb); voiddisplay();};template<classtype,inti>DemoClass<type,i>::DemoClass() //定义类模板的构造函数{

cout<<"DemoClassiscreated!"<<endl;}template<classtype,inti>DemoClass<type,i>::~DemoClass() //定义类模板的析构函数{

cout<<"DemoClassisdeleted!"<<endl;}template<classtype,inti>intDemoClass<type,i>::set(typea,intb) //定义类模板的成员函数{

if((b>=0)&&(b<i)) { array[b]=a; //为数组第b个元素赋值

returnsizeof(a); } else return-1;}template<classtype,inti>voidDemoClass<type,i>::display(){ for(intj=0;j<i;j++) //显示各个数组元素的值

cout<<j<<""<<array[j]<<endl;}voidmain(){ DemoClass<int,5>demo1; //实例化一个整数模板类,元素个数为5

for(intj=0;j<5;j++)demo1.set(10*j,j); demo1.display(); DemoClass<double,6>demo2; //实例化一个实数模板类,元素个数为6

for(j=0;j<6;j++) demo2.set(1010*j,j); demo2.display();}此程序的运行结果为:DemoClassiscreated!00110220330440DemoClassiscreated!00.000000110.1000220.2000330.3000440.4000550.5000DemoClassisdeleted!DemoClassisdeleted!返回本节3

类模板的友元1.一般的类模板友元函数2.封闭型的类模板友元函数3.开放型的类模板友元函数1.一般的类模板友元函数例6:利用函数模板方法求两个可比对象的大小,用模板函数返回具体的两个对象的较大者。#include<iostream.h>#include<complex.h>classMycomplex::publiccomplex{public: MyComplex():complex(0,0){} MyComplex(doubler,doublei):complex(r,i){} friendintoperator>(MyComplex&c1,MyComplex&c2);};intoperator>(MyComplex&c1,MyComplex&c2){ returnabs(c1)>abs(c2);}template<classT)T&Bigger(T&a,T&b){

return(a>b)?a:b;}voidmain(){ inti1=10,i2=20,i3; doubled1=1.1,d2=2.2,d3; MyComplexc1(1,2),c2(3,4),c3; i3=Bigger(i1,i2); d3=Bigger(d1,d2); c3=Bigger(c1,c2); cout<<"Theresultis:\n"<<"TheBiggerof"<<i1<<"and"<<i2<<"is"<<i3<<endl<<"TheBiggerof"<<d1<<"and"<<d2<<"is"<<d3<<endl<<"TheBiggerof"<<c1<<"and"<<c2<<"is"<<c3<<endl;}此程序的运行结果为:Theresultis:TheBiggerof10and20is20TheBiggerof11and2.2is2.2TheBiggerof(1,2)and(3,4)is(3,4)2.封闭型的类模板友元函数例7:类模板的友元函数。

#include<iostream.h>#include<iomanip.h>template<classTYPE>classArray{ TYPE*element; intsize;public: Array(intn){element=newTYPE[n];size=n;} ~Array(){deleteelement;} voidoperator=(TYPEx); TYPE&operator[](intindex); friendostream&operator<<(ostream&os,Array<TYPE>&a);};template<classTYPE>TYPE&Array<TYPE>::operator[](intindex){ return*(element+index);}

温馨提示

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

最新文档

评论

0/150

提交评论