u:57 第九章模板 本章主要内容 1.模板的概念 2.函数模板 3.类模板 4.容器与迭代子
21:17:57 第九章 模 板 本章主要内容 1. 模板的概念 2. 函数模板 3. 类模板 4. 容器与迭代子
u:57 §1模板的概念 模板用于表达逻辑结构相同,但具体数据元素类型不同的 数据对象的通用行为,是开发大型软件、建立通用函数库 和类库的强有力的工具 类属机制:把函数或类要处理的数据类型参数化,表现为 参数的多态性 C++中有两种模板 1.函数模板 2.类模板
21:17:57 §1 模板的概念 ➢ 模板用于表达逻辑结构相同,但具体数据元素类型不同的 数据对象的通用行为,是开发大型软件、建立通用函数库 和类库的强有力的工具 ➢ 类属机制:把函数或类要处理的数据类型参数化,表现为 参数的多态性 ➢C++中有两种模板 1. 函数模板 2. 类模板
模板存在的必要性 1.函数重载 int abs(int x return x>0?x:-x double abs (double x return x>0?x: -; long abs(long x)return x>0?x: -x; K int maino cout < abs (10)<< ends < abs(-10. 5)<< ends <abs(-1000000L)<<endl return 0 重载的多个函数只是处理的数据的类型不一样,除此之外, 其它操作完全一样,但针对每种数据类型都必须实现一个函 数完成相应的操作
21:17:57 模板存在的必要性 int abs(int x){return x>0?x:-x;} double abs(double x){return x>0?x:-x;} long abs(long x){return x>0?x:-x;} int main(){ cout << abs(-10) << ends << abs(-10.5) << ends << abs(-1000000L) << endl; return 0; } 1. 函数重载 重载的多个函数只是处理的数据的类型不一样,除此之外, 其它操作完全一样,但针对每种数据类型都必须实现一个函 数完成相应的操作
u1:57 2.链表类 class linKlist i 本链表类中只能保存整型 struct NODE I 数据,若要保存其它类型的 int 1 数据,必须另外创建一个 NODE next. 类,但类的结构、实现代码 )*head 几乎一样,只是其中的int public: 被相应的数据类型替换 LINKLIST O LINKLIST (LINKLIST&);问题: LINKLIST O 对不同的数据类型,代码 void Created 存在冗余,不利于代码重用 void Insert ( int 模板: 定义函数或创建类时,把数据的类型做为形式参数,调 用函数或定义对象时传以要处理数据的类型做为实际参数
21:17:57 解决办法: 把要操作的数据的类型 做为函数或类的参数 2. 链表类 class LINKLIST{ struct NODE { int i; NODE * next; }*head; public: LINKLIST(); LINKLIST(LINKLIST &); ~LINKLIST(); void Create(); void Insert(int i); void Remove(int i); NODE *Find(int i); }; 本链表类中只能保存整型 数据,若要保存其它类型的 数据,必须另外创建一个 类,但类的结构、实现代码 几乎一样,只是其中的int 被相应的数据类型替换 问题: 对不同的数据类型,代码 存在冗余,不利于代码重用 模板: 定义函数或创建类时,把数据的类型做为形式参数,调 用函数或定义对象时传以要处理数据的类型做为实际参数
u1:57 §2函数模板 定义语法:使用关键字 template template 返回值类型函数名(函数的形式参数表) 函数体;} 例:函数模板 1.abs0函数 template void maino t t Tabs t x) cout0?x cout<<Tabs(1000000)<<end 1;
21:17:57 §2 函数模板 ➢定义语法: 使用关键字template template 返回值类型 函数名(函数的形式参数表) { 函数体;} 例:函数模板 1. abs()函数 template T Tabs(T x) { return x>0?x:-x; } void main(){ cout<<Tabs(10)<<endl; cout<<Tabs(-10.5)<<endl; cout<<Tabs(-1000000)<<endl; }
u:57 2.Max0函数 template T Max t X, T y) void maino if (x>y) cout<<Max(10. 20)<<end1; return x cout<<Max(10.0. 20.0<<end 1: else cout<<Max(A, B)<<end1 return y;
21:17:57 2. Max()函数 template T Max(T x,T y) { if (x>y) return x; else return y; } void main() { cout<<Max(10,20)<<endl; cout<<Max(10.0,20.0)<<endl; cout<<Max('A','B')<<endl; }
u:57 冒泡排序的函数模板 template a[i+1]){ temp a li]; ali]= a[i+1]; a[i+1]= temp work =0 if work break
21:17:57 3. 冒泡排序的函数模板 template void SortBubble(ElementType *a,int size){ int i,work; ElementType temp; for(int pass =1;passa[i+1]){ temp = a[i];a[i] = a[i+1];a[i+1] = temp; work = 0; } } if (work) break; } }
u1:57 关于函数模板的说明 函数模板定义中类型形式参数表中的类型在函数模板的定 义中至少要使用一次 类型形式参数表中的类型不能是具体的某种类型,只能是 “通用”类型 编译时对函数模板不产生可执行代码(为什么?) 函数模板可直接调用 例:abs(-100000) 编译时,根据传递给函数的实参的类型,确认是否与函数 模板中对应的形参相匹配,若匹配则实参的类型替换函数 模板的函数形参列表中出现的类型参数,产生一个重载的 函数,该函数称为模板函数
21:17:57 关于函数模板的说明 ➢ 函数模板定义中类型形式参数表中的类型在函数模板的定 义中至少要使用一次 ➢ 类型形式参数表中的类型不能是具体的某种类型,只能是 “通用”类型 ➢ 编译时对函数模板不产生可执行代码 (为什么?) ➢ 函数模板可直接调用 例: abs(-100000); ➢ 编译时,根据传递给函数的实参的类型,确认是否与函数 模板中对应的形参相匹配,若匹配则实参的类型替换函数 模板的函数形参列表中出现的类型参数,产生一个重载的 函数,该函数称为模板函数
u1:57 函数模板可以重载:同一个函数模板得到的模板函数之间 是重载关系 1.函数模板之间的重载 template template T Max t a, t b) T Max(t a, t b, t c return a>b?a: b: return a>b?(a>c? a: c):(b>c? b: c) void maino i cout < Max(12, 120)<< end1; cout<<Max(10.0,100.0)<<end1; cout<<Max(12,120,1200)<end1; cout<<Max(10.0,100.0,100.0)<<end1;
21:17:57 ➢函数模板可以重载:同一个函数模板得到的模板函数之间 是重载关系 template T Max(T a,T b) { return a>b?a:b; } 1. 函数模板之间的重载 template T Max(T a,T b,T c) { return a>b?(a>c?a:c):(b>c?b:c); } void main(){ cout << Max(12,120) << endl; cout << Max(10.0,100.0) << endl; cout << Max(12,120,1200) << endl; cout << Max(10.0,100.0,1000.0) << endl; }
u1:57 2.函数模板与普通函数之间的重载 template char* Max(char *a, char *b) T Maxt a, t b) if (strcmp(a, b)>0)return a return a>b?a: b: else return b void maino( cout < Max(12, 120)<< end1; cout<<Max(12.5,120.5)<<end1; cout < Max("abCDe","abcde )< end1
21:17:57 2. 函数模板与普通函数之间的重载 template char* Max(char *a,char *b) T Max(T a,T b) { { if (strcmp(a,b)>0) return a; return a>b?a:b; else return b; } } void main(){ cout << Max(12,120) << endl; cout << Max(12.5,120.5) << endl; cout << Max("ABCDE","abcde") << endl; }