您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 数据通信与网络 > 全国计算机二级考试C++教程课件6
C++程序设计第6章模板6.1模板的概念6.2函数模板6.3类模板模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。例如,设计一个求两参数最大值的函数,不使用模板时,需要定义四个函数:intmax(inta,intb){return(ab)?a,b;}longmax(longa,longb){return(ab)?a,b;}doublemax(doublea,doubleb){return(ab)?a,b;}charmax(chara,charb){return(ab)?a,b;}若使用模板,则只定义一个函数:Templateclasstypetypemax(typea,typeb){return(ab)?a,b;}6.1模板的概念所谓模板是一种使用类型参数来产生一系列函数或类的机制,是C++的一个重要特性。它的实现,方便了更大规模的软件开发。若一个程序的功能是对某种特定的数据类型进行处理,则可以将所处理的数据类型说明为参数,以便在其他数据类型的情况下使用,这就是模板的由来。模板是以一种完全通用的方法来设计函数或类而不必预先说明将被使用的每个对象的类型。通过模板可以产生类或函数的集合,使它们操作不同的数据类型,从而避免需要为每一种数据类型产生一个单独的类或函数。C++程序由类和函数组成,模板也分为类模板(classtemplate)和函数模板(functiontemplate)。在说明了一个函数模板后,当编译系统发现有一个对应的函数调用时,将根据实参中的类型来确认是否匹配函数模板中对应的形参,然后生成一个重载函数。该重载函数的定义体与函数模板的函数定义体相同,它称之为模板函数(templatefunction)。同样,在说明了一个类模板之后,可以创建类模板的实例,即生成模板类。6.2函数模板C++提供的函数模板可以定义一个对任何类型变量进行操作的函数,从而大大增强了函数设计的通用性。使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行。函数模板说明:template模板形参表返回值类型函数名(模板函数形参表){//函数定义体}其中,模板形参表可以包含基本数据类型,也可以包含类类型。类型形参需要加前缀class。如果类型形参多于一个,则每个类型形参都要使用class。模板函数形参表中的参数必须是惟一的,而且函数定义体中至少出现一次。函数模板定义不是一个实实在在的函数,编译系统不为其产生任何执行代码。该定义只是对函数的描述,表示它每次能单独处理在类型形式参数表中说明的数据类型。使用函数模板函数模板只是说明,不能直接执行,需要实例化为模板函数后才能执行。当编译系统发现有一个函数调用:函数名(实参表);时,将根据实参表中的类型生成一个重载函数即模板函数。该模板函数的定义体与函数模板的函数定义体相同,而形参表的类型则以实参表的实际类型为依据。例:以函数重载方式输出不同类型数组中的数据。#includeiostream.hvoidprintArray(int*array,intcount){for(inti=0;icount;i++)coutarray[i];coutendl;}voidprintArray(double*array,intcount){for(inti=0;icount;i++)coutarray[i];coutendl;}voidprintArray(char*array,intcount){for(inti=0;icount;i++)coutarray[i];coutendl;}voidmain(){intCount=5,bCount=7,cCount=6;inta[aCount]={1,2,3,4,5,};doubleb[bCount]={1.1,2.2,3.3,4.4,5.5,6.6,7.7};charc[cCount]=HELLO;coutArrayacontains:endl;printArray(a,aCount);coutArraybcontains:endl;printArray(b,bCount);coutArrayccontains:endl;printArray(c,cCount);getch();}函数模板的创建和使用函数模板之所以能以同样的程序代码对不同类型的数据进行处理,其关键是将所处理的数据类型说明为参数,即类型参数化。定义函数模板的一般形式是:templateclass类型参数名1,class类型参数名2,…函数返回值类型函数名(形参表){函数体}说明:(1)这里的类型参数名就是代表形形色色数据类型的通用参数名,它可以代表基本数据类型,也可以代表类。(2)编写函数模板的方法是:第一步:定义一个普通的函数,数据类型采用具体的普通的数据类型,仍以打印数组为例,先定义一个打印整型数组的普通函数:voidprintArray(int*array,intcount){for(inti=0;icount;i++)coutarray[i];coutendl;}第二步:将数据类型参数化:将其中具体的数据类型名(如int)全部替换成由自己定义的抽象的类型参数名(如T)。第三步:在函数头前用关键字template引出对类型参数名的声明。这样就把一个具体的函数改造成一个通用的函数模板:templateclassT//注意末尾不要加分号voidprintArray(T*array,intcount)//注意用类型参数替换的是数据类型名,不是变量名{for(inti=0;icount;i++)coutarray[i];coutendl;}函数模板不是一个可以执行的函数,它只是对函数功能的程序描述,编译程序不为它生成执行代码。当编译程序遇到函数调用:函数名(实参表)时,自动将实参表中具体的数据类型替换函数模板中的类型参数,生成一个隐含的重载函数,该重载函数的程序代码与函数模板相同,类型则采用实参表中的具体数据类型。仍以前面所创建的打印数组函数模板为例,当程序出现函数调用语句printArray(a,aCount);时,编译程序将根据第一个实参a的数据类型int匹配类型参数T,将函数模板中的所有T都替换成具体的数据类型int,从而产生一个具体的可执行函数的定义(这个过程称为模板实例化):voidprintArray(int*array,intcount);例用函数模板方法重写上例#includeiostream.htemplateclassT//定义打印数组的函数模板voidprintArray(T*array,intcount){for(inti=0;icount;i++)coutarray[i];coutendl;}voidmain(){constintaCount=5,bCount=7,cCount=6;inta[aCount]={1,2,3,4,5,};doubleb[bCount]={1.1,2.2,3.3,4.4,5.5,6.6,7.7};charc[cCount]=HELLO;coutArrayacontains:endl;printArray(a,aCount);coutArraybcontains:endl;printArray(b,bCount);coutArrayccontains:endl;printArray(c,cCount);getch();}函数模板与模板函数函数模板是对一组函数的描述,它不是一个实实在在的函数,编译系统并不产生任何执行代码。当编译系统在程序中发现有与函数模板中相匹配的函数调用时,便生成一个重载函数,该重载函的函数体与函数模板的函数体相同。该重载函数称为模板函数。函数模板与模板函数的区别如下:(1)函数模板不是一个函数,而是一组函数的模板,在定义中使用了参数类型。(2)模板函数是一种实实在在的函数定义,它的函数体与某个模板函数的函数体相同。编译系统遇到模板函数调用时,将生成可执行代码。函数模板是定义重载函数的一种工具。一个函数模板只为一种原型函数生成一个模板函数,不同原型的模板函数是重载的。这样就使得一个函数只需编码一次就能用于某个范围的不同类型的对象上。因此,可以说函数模板是提供一组重载函数的样板对模板函数的说明和定义必须是全局作用域。模板不能被说明为类的成员函数。模板函数有一个特点,虽然模板参数T可以实例化成各种类型,但是采用模板参数T的各参数之间必须保持完全一致的类型。模板类型并不具有隐式的类型转换,例如在int与char之间、float与int之间、float与double之间等的隐式类型转换。而这种转换在C++中是非常普遍的。函数模板方法克服了C语言解决上述问题时用大量不同函数名表示相似功能的坏习惯;克服了宏定义不能进行参数类型检查的弊端;克服了C++函数重载用相同函数名字重写几个函数的繁琐。因而,函数模板是C++中功能最强的特性之一,具有宏定义和重载的共同优点,是提高软件代码重用率的重要手段。重载模板函数模板函数与普通函数一样,也可以重载。例:#includeiostream.h#includestring.htemplateclassTTmax(Ta,Tb){returnab?a:b;}char*max(char*a,char*b){return(strcmp(a,b)0?a:b);}voidmain(){coutMax(\Hello\,\Gold\)ismax(Hello,Gold)endl;getch();}函数charmax(char*,char*)中的名字max与函数模板的名字相同,但操作不同,函数体中的比较采用了字串比较函数,所以有必要用重载的方法把它们区分开,这种情况就是重载模板函数。编译程序在处理这种情况时,首先匹配重载函数,然后再寻求模板的匹配。编译程序看到max(Hello,Gold)调用时,先进行重载函数匹配,结果匹配了非模板函数charmax(char,char),所以这里不会为它产生模板函数的代码。6.3类模板类模板与函数模板类似,它可以为各种不同的数据类型定义一种模板,在引用时使用不同的数据类型实例化该类模板,从而形成一个类的集合。类模板实际上是函数模板的推广。可以用相同的类模板来组建任何类型的对象集合。类模板说明的一般形式是:template类型形参表class类名{//类说明体};template类型形参表返回类型类名类型名表::成员函数1(形参表){//成员函数定义体}…template类型形参表返回类型类名类型名表::成员函数n(形参表){//成员函数定义体}其中的类型形参表与函数模板中的意义一样。后面的成员函数定义中,类型名表是类型形参的使用。这样的一个说明(包括成员函数定义)不是一个实实在在的类,只是对类的描述,称为类模板(classtemplate)。类模板必须用类型参数将其实例化为模板类后,才能用来生成对象。一般地,其表示形式为:类模板名类型实参对象名(值实参表)其中类型实参表表示将类模板实例化为模板类时所用到的类型(包括系统固有的类型和用户已定义类型),值实参表表示将该模板类实例化为对象时其构造函数所用到的变量。一个类模板可以用来实例化多个模板类。类型形参表中的形参要加上class关键词,类型形参可以是C++中的任何基本的或用户定义的类型。对在形参表中定义的每个类型,必须要使用关键词class。如果类型形参多于一
本文标题:全国计算机二级考试C++教程课件6
链接地址:https://www.777doc.com/doc-6280121 .html