第13讲 模板与泛型编程_第1页
已阅读1页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

计算机学院计算机网络与信息安全研究室张荣博面向对象程序设计及C++第9章模板与泛型编程9.1模板概念(★)9.2函数模板9.3类模板9.4泛型编程(★)1教学目标了解泛型编程的概念及形式。重点及难点重点:类模板及函数模版的定义。难点:模板的应用。2模板的概念C++中常见的问题voidswap(int&a,int&b){

int

tmp=0;

tmp=a;a=b;b=tmp;}//交换两个浮点数voidswap(float&a,float&b){floattmp=0.0;

tmp=a;a=b;b=tmp;}intmain(){

inta=10,b=20;floatc=1.2,d=2.4;

cout<<“a=“<<a<<“b=”<<b;

cout<<“c=“<<c<<“d=”<<c;swap(a,b);cout<<“a=“<<a<<“b=”<<b;

swap(c,d);cout<<“c=“<<c<<“d=”<<c;return0;}3提出问题在上面例子中,两个swap函数实现的功能相同,只是参数类型不同,为了实现不同类型的数据交换必须重新编辑函数。造成了重复劳动。面向对象程序设计方法出现的目的之一是实现软件重用,能否提供一种方法将两个函数合并到一起,以节省开发成本?4解决方法typedef

int

DataType;voidswap(DataType&a,DataType&b){

DataType

tmp;

tmp=a; a=b; b=tmp;}intmain(){

inta=10,b=20;

swap(a,b);return0;}5分析问题当需要交换两个浮点数时可以将DataType

定义成float型数据即可。缺点:

更改一种数据类型时,需要修改程序源代码,必须重新编译程序。无法解决的问题:

如果程序中需要交换多种数据类型之间的数据该怎么办?6typedef

int

DataType;voidswap(DataType&a,DataType&b){

DataType

tmp;

tmp=a; a=b; b=tmp;}intmain(){

inta=10,b=20;

floatc=1.2,d=2.4;

swap(a,b);

swap(c,d);return0;}能否将swap函数的形式参数,作为一种无类型的参数,当使用它的时候再将它用具体的参数实现?就像采用滞后捆绑实现多态一样!7模板的定义模板本质上就是参数化多态,是一种使用无类型参数来产生一系列函数或类的机制,是C++的一个重要特性。模板可以分为两类:函数模板类模板8函数模板与模板函数函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计。声明方法:

template

<class

T>

//模板声明

Tmax(Tx,Ty) //定义函数模板

{ return(x>y)?x:y;}9模板函数max代表的是一类函数,是函数的集合;要用max进行真正的操作前,先要将模板参数T实例化为一般的类型(如int

等);max是一个函数模板,将T实例化的参数称为模板实参,用模板实参实例化的函数称为模板函数。template<classT>//模板声明Tmax(Tx,Ty){return(x>y)?x:y;}10例题#include<iostream>usingnamespacestd;template<classT>Tmax(Tx,Ty){return(x>y)?x:y;}voidmain(){

inti=10,j=56; floatx1=50.34f,x2=56.34f; doubley1=673.36,y2=465.972;

cout<<"Themaxofi,jis:"<<max(i,j)<<endl;

cout<<"Themaxofx1,y1is:"<<max(x1,x2)<<endl;

cout<<"Themaxofx2,y2is:"<<max(y1,y2)<<endl;}11

cout<<"Themaxofi,jis:"<<max(i,j)<<endl;当编译器遇到max(i,j)时,生成函数名max(int,int):用模板实参int将类型参数T进行了实例化。

cout<<"Themaxofx1,y1is:"<<max(x1,x2)<<endl;当编译器遇到max(x1,x2)时,生成函数名max(float,float):用模板实参float将类型参数T进行了实例化。

cout<<"Themaxofx2,y2is:"<<max(y1,y2)<<endl;当编译器遇到max(y1,y2)时,生成函数名max(double,double):max(y1,y2)用模板实参double将类型参数T进行了实例化12

因此,上例中max函数可以用显式模板类型的方法写成下面的形势:

voidmain() {

inti=10,j=56;

floatx1=50.34f,x2=56.34f;

doubley1=673.36,y2=465.972;

cout<<"Themaxofi,jis:“ <<max<int>(i,j)<<endl;

cout<<"Themaxofx1,y1is:“

<<max<float>(x1,x2)<<endl;

cout<<"Themaxofx2,y2is:“ <<max<double>(y1,y2)<<endl; }13模板参数表:是由若干个模板参数组成的。各参数间用逗号隔开,每个模板参数均是由类型参数和参数说明两部分,而类型参数指的是class标识符。 例如:

template

<classT1,class

T2,classT3>//模板声明

T1fun(T2x,T3y){ ……..}多个不定参数的模板函数的定义14注意:一般用T作为模板参数标识符,T代表任意类型。但实质上用任何字母都可以:如:template<classS>或template<classa>。

函数模板小结15类模板与模板类的概念

类模板:一个类模板允许用户为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型。它的存在不代表一个具体的、实际的类,而是代表一类的类,是类的集合。16

类模板的定义

template<classT>

//声明一个类模板

classclassname{

intNo;

Tvalue;public:

TGetValue(){returnvalue;}voidSetValue(T&v){value=v;}};17在类定义体外定义成员函数时,若此成员函数中有模板参数存在,则需在函数体外进行模板声明,并且在函数名前的类名后缀上”<T>”。

template<classT>

voidclassname<T>::SetValue(T&v){

vulae=v;}template<classT>

Tclassname<T>::GetValue(){returnvulae;}18类模板的使用类模板的使用。类模板的使用实际上是将类模板实例化成一个具体的类,它的格式为:类名

<实际的类型>对象名;intmain(){

classname<float>obj; obj.SetValue(1.0);

float

tmp=obj.GetValue();}19//举例定义类#include<iostream>using

namespace

std;template<classT>//声明模板classnode{//定义结构模板

Tval;//val取任意类型,即模板参数类型

node<T>*next;//此处node为结构模板};template<classT>//声明模板classlist{//定义类模板

node<T>*head;//此处node为结构模板

intsize;public: list(){head=NULL;size=0;}

boolinsert(Tval);voidprint();~list();};链表类模板的定义20//定义成员函数,插入函数template<classT>boollist<T>::insert(Tx){ node<T>*nodes=newnode<T>;

if(nodes) { nodes->val=x; nodes->next=head; head=nodes; size++;

return

true; }

return

false;}21//定义成员函数输出函数template<classT>voidlist<T>::print(){

for(node<T>*p=head;p;p=p->next)

cout<<p->val<<"";

cout<<endl;}//析构函数template<classT>//声明模板list<T>::~list()//定义函数模板,其中list为类模板{ node<T>*temp;//node为结构模板

for(node<T>*p=head;p;){ temp=p; p=p->next;

deletetemp; }}22//类模板的使用voidmain(){//定义一个整型链表对象,此时传进来的模板参数为<int> list<int>intlist; intlist.insert(34); intlist.insert(54);

intlist.print();

//定义一个浮点型链表对象,此时传进来的模板参数为<float>list<float>floatlist; floatlist.insert(34.56f);floatlist.insert(65.4f);

floatlist.print();

//定义一个字符串型链表对象,此时传进来的模板参数为<char*> list<char*>charlist;

charlist.insert("windows");

charlist.insert("object");

charlist.print();}543465.434.56objectwindows23类模板总结24模板、类、对象、函数之间的关系25群体的概念群体是指由多个数据元素组成的集合体。群体可以分为两个大类:线性群体和非线性群体。线性群体中的元素按位置排列有序(数组)。非线性群体不用位置顺序来标识元素(链表)。26泛型编程将程序写得尽可能通用;将算法从特定的数据结构中抽象出来,成为通用的;C++的模板为泛型程序设计奠定了关键的基础;STL是泛型程序设计的一个范例。容器(container)迭代器(iterator)算法(algorithms)函数对象(functionobject)27容器容器类是容纳、包含一组元素或元素集合的对象。异类容器类与同类容器类顺序容器与关联容器七种基本容器:

向量(vector)、双端队列(deque)、列表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)28容器的接口通用容器运算符==,!=,>,>=,<,<=,=方法(函数)迭代方法(指针的移动)begin(),end(),rbegin(),rend()访问方法size(),max_size(),swap(),empty()29适配器与迭代器适配器是一种接口类(栈适配器)为已有的类提供新的接口。目的是简化、约束、使之安全、隐藏或者改变被修改类提供的服务集合。迭代器是面向对象版本的指针,它们提供了访问容器、序列中每个元素的方法30算法与函数对象C++标准模板库中包括70多个算法其中包括查找算法,排序算法,消除算法,记数算法,比较算法,变换算法,置换算法和容器管理等等。函数对象一个行为类似函数的对象,它可以没有参数,也可以带有若干参数,其功能是获取一个值,或者改变操作的状态。31顺序容器——向量向量属于顺序容器,用于容纳不定长线性序列(即线性群体),提供对序列的快速随机访问(也称直接访问)向量是动态结构,它的大小不固定,可以在程序运行时增加或减少。向量是应用较多的STL容器。例题:求范围2~N中的质数,N在程序运行时由键盘输入。32//10_

温馨提示

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

评论

0/150

提交评论