《《C++程序设计教程》-杨国兴-电子教案及例题 第9章 模板》由会员分享,可在线阅读,更多相关《《C++程序设计教程》-杨国兴-电子教案及例题 第9章 模板(24页珍藏版)》请在金锄头文库上搜索。
1、第9章 多态性,9.1 函数模板 9.2 模板函数的覆盖 9.3 类模板,9.1 函数模板,1. 问题的提出 重载函数可以解决功能相同或相似的函数使用同一个函数名的问题。 void swap(char ,第9章 模板,void swap(float ,实际代码量并未减少。可使用函数模板减少大量代码。,9.1 函数模板,2. 函数模板的定义 template 或 类型名 函数名(参数表) 函数体 函数模板就像是一个带有类型参数的函数(参数T即为类型),编译程序会根据实际参数的类型确定参数的类型。,第9章 模板,template 类型名 函数名(参数表) 函数体 ,例9.1 定义用于变量交换的函数
2、模板,#include template void swap(T ,第9章 模板,程序运行结果为: B, A 456, 123 45.6, 12.3,例9.2 插入排序函数模板,使用插入排序函数模板可以为不同数据类型的数组排序,如整型、字符型、实型等等,为了使程序具有通用性,设计函数模板InsertionSort()。,插入排序的基本思想:每一步将一个待排序的元素按其关键字值的大小插入到已排序序列的合适位置,直到待排序元素全部插入完为止。,第9章 模板,例9.2 (续一),template void InsertionSort(T A, int n) int i, j; T temp; for
3、 (i = 1; i 0 ,第9章 模板,例9.2 (续二),#include void main() int a10=2,4,1,8,7,9,0,3,5,6; double b10=12.1, 24.2, 15.5, 81.7, 2.7, 5.9, 40.3, 33.3, 25.6, 4.6; InsertionSort(a,10); InsertionSort(b,10); cout a0 “ “ a1 “ “ a2 “ “ a3 “ “; cout a4 “ “ a5 “ “ a6 “ “ a7 “ “; cout a8 “ “ a9 endl; cout b0 “ “ b1 “ “ b
4、2 “ “ b3 “ “; cout b4 “ “ b5 “ “ b6 “ “ b7 “ “; cout b8 “ “ b9 endl; ,第9章 模板,程序运行结果为: 0 1 2 3 4 5 6 7 8 9 2.7 4.6 5.9 12.1 15.5 24.2 25.6 33.3 40.3 81.7,例9.3 使用函数模板产生的二意性,#include template T max(T a, T b) return ab?a:b; void main(void) int a = max(10.5, 20); double b = max(10, 20.6); cout a endl; co
5、ut b endl; ,第9章 模板,9.2 模板函数的覆盖,下列函数模板: template T max(T a, T b) retum ab?a:b; 对于简单的数据类型,如整型、实型、字符型数据,这个模板能够正常工作。对于字符串,用上述模板就会出现问题,因为对于字符串,不能使用运算符“”,要为其编写独立的max()函数。 我们将函数模板生成的函数称为模板函数。如果某一函数的函数原型与函数模板生成的函数(模板函数)原型一致,称该函数为模板函数的覆盖函数。,第9章 模板,例9.4 模板函数的覆盖,#include #include template T max(T a, T b) retur
6、n ab?a:b; char *max(char *x, char *y) return strcmp(x, y) 0 ? x :y; void main(void) char *p=“ABCD“, *q=“EFGH“; p=max(p, q); int a =max(10, 20); float b =max(10.5, 20.6); cout p endl; cout a endl; cout b endl; ,第9章 模板,程序运行结果为: EFGH 20 20.6,9.2 模板函数的覆盖,在进行函数调用时,编译程序采用如下策略确定调用哪个函数: (1)首先寻找一个实参与形参完全匹配的覆
7、盖函数,如果找到,则调用该函数 (2)如果能通过函数模板生成实例函数,并且参数匹配,则调用该函数。 (3)通过强制类型转换,寻找能够与实参匹白的覆盖函数,或通过函数模板生成的实例函数、如果找到则调用该函数。 (4)如果所有努力失败,则给出出错信息。,第9章 模板,9.3 类模板,1. 问题的提出 class A int i; public: A(int a) void set (int b) ; class B double i; public: B(double a) void set (double b) ;,第9章 模板,这两个类的方法都一样,只是一个数据类型是整型,另一个数据类型是实型
8、。可以使用类模板简化代码,类模板也称为参数化的类,用于为类型相似的类定义一种通用模式,9.3 类模板,2. 类模板的定义 template class 类模板名 成员声明 如果需要在类模板外定义类模板的成员函数,格式如下: template 类型 类模板名:函数名(参数表) 函数体 ,第9章 模板,9.3 类模板,2. 类模板的定义(续) 使用类模板建立对象的语法如下: 类模板 对象1,对象2,; 系统会根据实参的类型,生成一个类(称为模板类),然后建立该类的对象。即对模板实例化生成类,再对类实例化生成对象。,第9章 模板,例9.5 定义数组类的类模板,并利用成员函数对数组中的元素初始化。,#
9、include template class myArray public: myArray(int nSize,T Initial); myArray() delete m_pArray; T ,第9章 模板,例9.5 (续一),template myArray:myArray(int nSize,T InitVal) m_nSize=(nSize1)? nSize:1; m_pArray=new Tm_nSize; for(int i=0;i void myArray:Show(int nNumElems, char *pszMsg, bool bOneLine) cout pszMsge
10、ndl; if(bOneLine) for(int i=0;inNumElems;i+) cout m_pArrayi ; cout endl; else for(int i=0;inNumElems;i+) cout m_pArrayiendl; ,第9章 模板,构造函数为m_nSize赋值,并为数组申请存储空间,将数组的每个元素都赋值为InitVal。,成员函数Show()显示数组元素的值,元素的个数由第一个参数指定,第二个参数为输出数组元素值之前,输出的提示信息,第三个参数确定数组元素是显示在一行上,还是多行。,例9.5 (续二),template void myArray:Sort(i
11、nt nNumElems) int i, j; T temp; for (i = 1; i 0 ,第9章 模板,成员函数Sort()使用插入排序法对数组元素排序(升序),其参数是数组中元素的个数。,例9.5 (续三),void main() int nArr10=89,34,32,47,15,81,78,36,63,83; int cArr10=C,W,r,Y,k,J,X,Z,y,s; myArray IntegerArray(10,0); myArray CharArray(10, ); for(int i=0;i10;i+) IntegerArrayi=nArri; for(i=0;i10
12、;i+) CharArrayi=cArri; IntegerArray.Show(10,“Unsorted array is: “); IntegerArray.Sort(10); IntegerArray.Show(10,“Sorted array is: “); cout endl ; CharArray.Show(10,“Unsorted array is: “); CharArray.Sort(10); CharArray.Show(10,“Sorted array is: “); cout endl; ,第9章 模板,程序运行结果为: Unsorted array is: 89 34
13、 32 47 15 81 78 36 63 83 Sorted array is: 15 32 34 36 47 63 78 81 83 89 Unsorted array is: C W r Y k J X Z y s Sorted array is: C J W X Y Z k r s y,例9.6 使用缺省参数定义数组的类模板,#include template class Array T *data; int size; public: Array(int); Array(); T ,第9章 模板,template Array :Array(int n) data = new Tsiz
14、e=n; template Array :Array() delete data; template T ,注意:函数模板不能定义缺省参数,而类模板却可以定义缺省参数。,例9.6 (续),void main(void) int i; Array L1(10); /等价于Array L1(10) Array L2(20); for(i=0; i10; i+) L1i = i; for(i=0; i20; i+) L2i = A+i; for(i=0; i10; i+) cout L1i “ “; cout endl; for(i=0; i20; i+) cout L2i “ “; cout en
15、dl; ,第9章 模板,程序运行结果为: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T,例9.7 折半查找函数模板,第9章 模板,基本思想:对于已按关键字排序的序列,经过一次比较,可将序列分割成两部分,然后只在有可能包含待查元素的一部分中继续查找,并根据试探结果继续分割,逐步缩小查找范围,直至找到或找不到为止。比如在如下数组中查找值为48的元素:,例9.7 (续一),template int BinSearch(T list, int n, T key) int mid, low, high; T midvalue; low=0; high=n-1; while (low = high) / low = high表示整个数组尚未查找完 mid = (low+high)/2; / 求中间元素的下标 midvalue = listmid; / 取出中间元素的值 if (key = midvalue) return mi