版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面向对象程序设计
第六章模板
C++Templates杨卫东左峥嵘华中科技大学自动化学院2017秋参考资料C++primer第四版
EffectiveC++3rdC++Templates(简体中文版).pdf内容
模板的定义函数模板类模板标准模板库STL问题提出实现一个函数,输入2个变量,输出这两个变量中值比较大的元素。要求:此函数可以接受int,char以及double类型的参数。C语言实现://函数1charMaxOfChar(charcNum1,charcNum2){return(cNum1>cNum2)?cNum1:cNum2;}//函数2intMaxOfInt(intiNum1,intiNum2){return(iNum1>iNum2)?iNum1:iNum2;}//函数3doubleMaxOfDouble(doubledNum1,doubledNum2){return(dNum1>dNum2)?dNum1:dNum2;}C语言函数重载c++时代,由于存在重载的概念,所以实现起来应该是这个样子://函数1charMax(charcNum1,charcNum2){return(cNum1>cNum2)?cNum1:cNum2;}//函数2intMax(intiNum1,intiNum2){return(iNum1>iNum2)?iNum1:iNum2;}//函数3doubleMax(doubledNum1,doubledNum2){return(dNum1>dNum2)?dNum1:dNum2;}#defineMAX(x,y)((x>y)?x:y)函数名字统一但代码量没有什么变化能否进一步?C++宏定义宏定义#defineMax(Inputl,Input2)((Inputl>Input2)?Inputl:Input2)宏无类型检查,不建议模板(函数模板)template<classT>TMax(constT&Inputl,constT&Input2){return(Inputl>Input2)?Inputl:Input2;}可以接受任何类型的参数,包括上边提到的int,char,double,甚至任何自定义类型(只要你实现了它的比较运算符operator>)具体选用什么样的实际函数是在编译时刻就决定好的,丝毫不会影响运行时的效率Input参数中用的是const&的,好处是减少函数调用时候的开销,因为我们不知道T类型到底有多大模板定义代码重用是程序设计的重要特性,为实现代码重用,使得代码具有更好的通用性,需要代码不受数据类型的限制,自动适应不同的数据类型,实现参数化程序设计。模板是C++中进行通用程序设计的工具之一模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型如希望函数或类能够处理多种不同类型数据,可以通过模板为函数或类设计一个通用样板(通用数据类型),当处理实际数据时,根据给定数据的实际类型来确定模板是c++语言最强大却最少被使用的特征之一,便于重复利用已经开发好的数据结构和算法,可以提高代码的复用性和开发效率,是通用编程实现方法之一。在c++中,模板让程序员能够定义一种使用不同类型对象的行为。比方用模板类定义一种链表,那么通过不同的模板参数〔在调用时提供〕,可以生成不同类型的链表有点像宏,但是宏不是类型平安的,而模板是类型平安的分函数模板和类模板两种模板的特点6.1
函数模板
1、数据类型作为参数的背景例:求绝对值的函数intabs(intx){ returnx<0?-x:x;}doubleabs(doublex){ returnx<0?-x:x;}特点:算法完全相同,仅仅只是数据类型不同。(函数重载)问题:能否以数据类型作为参数,实现通用代码设计。
2、模板模板是由可以使用任何数据类型的通用代码构成。模板以数据类型作为参数。模板的定义形式是:template<typename标识符>函数定义说明:template是关键字,表示定义的是模板。<>括起来的是模板的参数,可以有一个或多个。如:template<classT>或者:template<classT1,classT2>
3、例子定义一个求绝对值函数的模板。#include<iostream.h>template<typenameT>Tabs(Tx){ returnx<0?-x:x;}voidmain(){ intn=-5; doubled=-5.5; cout<<abs(n)<<endl;//由n的类型为int推导出T为int cout<<abs(d)<<endl;//由d的类型为double推导出T为double}分析:编译器调用abs()时,用其实参的类型推导出函数模板的类型参数。当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数。以abs(n)调用为例,编译器将生成一个函数:intabs(intx){ returnx<0?-x:x;}编译过程举例——函数模板支持所有数据类型的函数模板template<classT>inlineTsquare(Tx){ Tresult; result=x*x; returnresult;};Test62_pow2.cppTMatrix.dsw举例1——数组//模板,动态数组,类型T1D,2D,高维?template<typenameT,int_m,int_n>classDynamic2Dim{public:Dynamic2Dim();~Dynamic2Dim(); Dynamic1Dim<T,_n>&operator[](intindex);protected:public: Dynamic1Dim<T,_n>*m_pBuf;};template<typenameT,int_size>classDynamic1Dim{public:Dynamic1Dim();~Dynamic1Dim();T&operator[](intindex);protected:public:T*m_pBuf;};Test61_ArrType.cpp Dynamic1Dim<Dynamic1Dim<Dynamic1Dim<TYPE1,5>,5>,2>_TD31;举例2——矩阵template<classType>classMatrix{public://constructorsanddestructorMatrix();Matrix(constMatrix<Type>&A);Matrix(introws,intcolumns,constType&x=Type(0));Matrix(introws,intcolumns,constType*v);~Matrix();//assignmentsMatrix<Type>&operator=(constMatrix<Type>&A);Matrix<Type>&operator=(constType&x);Test62_TmatrixsDemo.dsw模板是C++支持参数化的工具使用类模板使用户可以为类声明一种模式,使类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能够取任意类型。类模板的声明形式如下:template<模板参数表>类声明模板参数表为:class标识符;如:template<classT>模板参数表包含上面多项内容时,各项内容以逗号分隔。模板类的成员函数必须是函数模板
6.2类模板在类模板首部以外的成员函数定义都要以下面的形式开头。template<classT>与函数模板相同,类模板只有使用的时候才被具体化为某一种类型用模板类创立对象的一般形式:模板<模板参数表>对象名1,对象名2,…,对象名n;模板参数表为用逗号分隔的假设干类型标识符或常量表达式构成。6.2类模板#include<iostream.h>#include<stdlib.h>//结构体StudentstructStudent{intid;//学号floatgpa;//平均分};template<classT>//类模板:实现对任意类型数据进行存取classStore{private:Titem;//item用于存放任意类型的数据inthaveValue;//haveValue标记item是否已被存入内容
public:Store(void);//缺省形式〔无形参〕的构造函数
TGetElem(void);//提取数据函数voidPutElem(Tx);//存入数据函数};举例//以下实现各成员函数。//注意:模板类的成员函数,假设在类外实现,那么必须是模板函数//缺省形式构造函数的实现template<classT>Store<T>::Store(void):haveValue(0){}//提取数据函数的实现template<classT>TStore<T>::GetElem(void){//如果试图提取未初始化的数据,那么终止程序if(haveValue==0){cout<<"Noitempresent!"<<endl;exit(1);}returnitem;//返回item中存放的数据}//存入数据函数的实现template<classT>voidStore<T>::PutElem(Tx){haveValue++;//将haveValue置为TRUE,表示item中已存入数值
item=x;//将x值存入item}voidmain(void){Studentg={1000,23}; //定义Student类型结构体变量的同时赋以初值
Store<int>S1,S2; //定义两个Store类对象,其中数据成员item为int类型
Store<Student>S3; //定义Store类对象S3,其中数据成员item为Student类型
Store<double>D; //定义Store类对象D,其中数据成员item为double类型
S1.PutElem(3);//向对象S1中存入数据〔初始化对象S1〕S2.PutElem(-7);//向对象S2中存入数据〔初始化对象S2〕cout<<S1.GetElem()<<""<<S2.GetElem()<<endl; //输出对象S1和S2的数据成员
S3.PutElem(g);//向对象D中存入数据〔初始化对象D〕cout<<"Thestudentidis"<<S3.GetElem().id<<endl; //输出对象S3的数据成员//D.PutElem(6.5);cout<<"RetrievingobjectD"; cout<<D.GetElem()<<endl;//输出对象D的数据成员 //由于D未经初始化,在执行函数D.GetElement()过程中导致程序终止}运行结果:类模板举例//EXAMPLE9_01.H#ifndefEXAMPLE9_01_H#defineEXAMPLE9_01_Htemplate<classT>classMax//声明类模板Max{private:Titem1,//类型为T,T在该类的对象生成时具体化
item2,item3;public:Max(){}Max(Tthefirst,Tthesecond,Tthethird);TGetMaxItem();//求得3个元素中的最大值并按类型T返回
voidSetItem(Tthefirst,Tthesecond,Tthethird);//设置类中的3个元素的值}#endif//EXAMPLE9_01B.H
//类模板的实现#ifndefEXAMPLE9_01B_H#defineEXAMPLE9_01B_Htemplate<classT>TMax<T>::Max(Tthefirst,Tthesecond,Tthethird): item1(thefirst),item2(thesecond),item3(thethird){return;}template<classT>voidMax<T>::SetItem(Tthefirst,Tthesecond,Tthethird){item1=thefirst;item2=thesecond;item3=thethird;}template<classT>TMax<T>::GetMaxItem()
〔续〕{Tmaxitem;maxitem=item1>item2?item1:item2;maxitem=maxitem>item3?maxitem:item3;returnmaxitem;}#endif//EXAMPLE9_1.CPP//主程序#include<iostream.h>#include″EXAMPLE901.H″#include″EXAMPLE901B.H″voidmain(){Max<int>nmyMax(1,2,3);Max<double>dblmyMax(1.2,1.3,-1.4);cout<<nmyMax.GetMaxItem()<<endl;cout<<dblmyMax.GetMaxItem()<<endl;}〔续〕C++标准模板库STLSTL(StandardTemplateLibrary)C++STLTraining.pdfC++标准模板库STL介绍.pdf标准模板库STL〔StandardTemplateLibrary〕,即标准模板库,是一个具有工业强度的、高效的C++程序库。它被容纳于C++标准程序库〔C++StandardLibrary〕中,是ANSI/ISOC++标准中最新的也是极具革命性的一局部。该库包含了诸多在计算机科学领域里所常用的根本数据结构和根本算法,为广阔C++程序员们提供了一个可扩展的应用框架,高度表达了软件的可复用性。这种现象有些类似于MicrosoftVisualC++中的MFC〔MicrosoftFoundationClassLibrary〕,或者是BorlandC++Builder中的VCL(VisualComponentLibrary)。STL是最新的C++标准函数库中的一个子集,这个庞大的子集占据了整个库大约80%的分量。STL的引入STL〔StandardTemplateLibrary,标准模板库〕是惠普实验室开发的一系列软件的统称。STL提供了一系列具有良好结构的通用C++组件,这些组件提供强大的功能。标准库的设计必须确保所有的模板算法既能操作库中的数据类型,也能操作C++固有的数据类型。例如,所有的算法都适用于普通指针类型。库中各组件功能是独立的,或者说,用户可以自己设计算法操作库提供的数据结构,也可以使用标准库的算法操作自定义的数据类型。STL概貌把软件部件想象成一个三位空问。第i维表示数据类型(int,double,char,...),第j维表示容器(array,linked-list,…),第k维表示算法(sort,merge,search,…)数据
算法容器STL优势需要设计i*j*k个不同的代码版本,比方整数数组的排序算法、double数组的排序算法,doublelinked-list的搜索算法…通过使用数据类型作为参数的模板函数,i轴可取消,仅需要设计j*k个不同的代码下一步是让算法可以工作在不同的容器上,这就意味着排序算法既可以用在array上,也可用在linked-list上。只需设计j+k个不同的代码版本了STL具体化了上述思想,期望通过减少开发时问以简化软件开发,简化调试、维护并增加代码的可移植性,其使用的算法非常可靠且效率高STL组成STL包含5个主要的局部:算法(Algorithm):能运行在不同容器(container)上的计算过程容器((Container):能够保存并管理对象的对象迭代器(Iterator):算法存取容器(algorithm-accesstocontainers)的抽象,以便算法可以应用在不同的容器上函数对象(FunctionObject):定义了函数调用操作符(operatorU)的类适应器(Adaptor):封装一个部件以提供另外的接口(例如用list实现stack)容器(Container)容器类型标准STL序列容器:vector、string、deque和list标准STL关联容器:set、multiset、map和multimap非标准序列容器slist和rope非标准的关联容器hash_set、hase_multiset、hash_map和hash_multimap容器容器局部主要由头文件<vector>、<list>、<deque>、<set>、<map>、<stack>和<queue>组成。对于常用的一些容器和容器适配器〔可以看作由其他容器实现的容器〕。数据结构描述实现头文件向量(vector)连续存储的元素<vector>列表(list)由节点组成的双向链表,每个节点包含着一个元素<list>双队列(deque)连续存储的指向不同元素的指针所组成的数组<deque>集合(set)由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序<set>多重集合(multiset)允许存在两个次序相等的元素的集合<set>容器数据结构描述实现头文件栈(stack)后进先出的值的排列<stack>队列(queue)先进先出的执的排列<queue>优先队列(priority_queue)元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列<queue>映射(map)由{键,值}对组成的集合,以某种作用于键对上的谓词排列<map>多重映射(multimap)允许键对有相等的次序的映射<map>迭代器(Iterator)算法和函数对象二分搜索的根本算法(genericbianrysearchalgorithm),给定一个排好序的整数数组,要求二分搜索某个值的位置适应器(Adaptor),是提供接口映射的模板类。适应器基于其他类来实现新的功能,合并以得到新的功能。成员函数可以被添加、隐藏,也可合并举例——容器#include<set>#include<iostream>usingnamespacestd;intmain(intargc,char*argv[]){set<string>strset;set<string>::iteratorsi;strset.insert("cantaloupes");strset.insert("apple");strset.insert("orange");strset.insert("banana");strset.insert("grapes");strset.insert("grapes");for(si=strset.begin();si!=strset.end();si++){cout<<*si<<"";}return0;}1.包含10个元素的序列逐个插入vector容器中,插入完成后将vector容器中的所有元素输出。【解答】该试题主要考查vector容器的使用。根据前面的学习,读者知道vector容器利用索引直接存取任何一个元素,在尾部插入元素或移除元素均非常快速。2.编写一个C++程序,创立了一个矢量容器〔STL的和数组等价的对象〕,并使用迭代器在其中搜索,找到值为100的元素。【解答】该试题主要考查迭代器在容器中的使用。该试题可以使用vector容器来实现存储数据,其相当于数组,通过迭代器的begin()和end()方法表示容器的首尾,通过循环语句依次对容器中的所有元素进行比较,直到找到指定元素为止STL小结掌握STL可以使你的程序结构更合理,数据存储和管理更科学,掌握STL的精华本质所在,真正理解泛型编程的意义。模板使得数据结构和类型别离,而STL算法只通过某个数据结构的几个根本的语义属性,屏蔽了数据结构的特定实现,成功的将算法与数据结构别离,在没有效率损失的前提下,得到了及大的弹性。STL可以看作是由不同的逐渐组成的系统,理解容器、迭代器、适配器的概念十分重要,在此根底上,真正理解STL算法的本质。有些算法被表示为容器类方法,但大量STL算法都是通用的、非成员函数的,这时将迭代器作为容器和算法间的接口来实现的,另外,STL算法通过迭代器和指针的概念融合,可用于非STL容器,如常规数组、以及后面要介绍的string对象等。从零开始学C++之STL〔二〕:实现简单容器模板类Vec〔vectorcapacity增长问题、allocator内存分配器〕举例——通用链表类用类模板实现通用链表类。将链表类结点的数据类型参数化,构成了一个通用模板,可以用来生成结点数据为任意类型的链表。//EXAMPLE9_02.H#ifndefEXAMPLE9_02_H#defineEXAMPLE9_02_H#include<iostream.h>#include<stdlib.h>template<classT>classListNode//结点类{public:ListNode(){}//结点类构造函数
ListNode(constT&nItem,ListNode<T>*ptrNext=NULL);//结点类带参数构
//造函数
T&ShowDate(){returnDate;}//返回本结点数据的引用
voidInsertAfter(ListNode<T>*ptr);//插入新结点作为本结点的后续结点
ListNode<T>*DeleteAfter(void);//删除本结点的后续结点
ListNode<T>*NextListNode()const;//获得本结点的后续结点的指针
voidSetNext(ListNode<T>*ptr){ptrNext=ptr;}//设置本结点的后续结点指针private:TDate;//本结点的数据
ListNode<T>*ptrNext;//指向本结点的后续结点的指针};template<classT>classLinkedList//链表类的声明及其实现{public:LinkedList(void);LinkedList(constLinkedList<T>&list);//拷贝构造函数~LinkedList(void){DeleteAll();}//析构函数,释放链表占用的资源
LinkedList<T>&operator=(constLinkedList<T>&list);//″=″号运算符
//的重载
voidNext();//指向链表的下一个结点
intEndOfList()const{return(!ptrCurr);}//判断链表当前位置是否是表尾
intCurrPosition()const{returnnPosition;}//获得当前位置指针在链表中的位置〔续〕voidInsertFront(constT&nItem);//将数据为nItem的结点插入到链表头
voidInsertTail(constT&nItem);//将数据为nItem的结点插入到链表尾
voidInsertAt(constT&nItem);//将数据为nItem的结点插入到链表的当前位置
voidInsertAfter(constT&nItem);//将数据为nItem的结点插入到链表的当前
//位置之后
voidInsertOrder(TnItem);
//将数据为nItem的结点插入到排序链表中,并构成新的排序链表
intDeleteHead();//删除链表头结点
voidDeleteCurr();//删除链表当前结点
voidDelete(Tkey);//删除链表中数据为key的结点
voidDeleteAll();//删除链表中的所有结点
T&GetDate();//得到链表中的当前结点数据
voidDisplayList();//显示链表中所有结点的数据
intFind(T&nItem);//在链表中找到数据为nItem的结点
intListLength()const{returnnListLength;};//求链表的长度
intListEmpty()const{returnnListLength;}//判断链表是否为空
voidReset(intnPos=0);//重新设置链表的当前指针的位置
〔续〕private:ListNode<T>*ptrFront,//链表的头结点指针*ptrTail,//链表的尾结点指针*ptrPrev,//链表的当前结点的前一个结点的指针*ptrCurr;//链表的当前结点指针
intnListLength;//链表的长度
intnPosition;//链表的当前结点指针的位置
ListNode<T>*GetListNode(constT&nItem,ListNode<T>*ptrNext=NULL);
//获得链表的下一个结点指针
voidFreeListNode(ListNode<T>*ptr){deleteptr;}//释放结点资源
voidCopyList(constLinkedList<T>&list);//逐项拷贝链表};#endif//EXAMPLE9_02B.H#ifndefEXAMPLE9_02B_H#defineEXAMPLE9_02B_H#include<iostream.h> 〔续〕#include″EXAMPLE9_02.H″//结点类带参数构造函数的实现template<classT>ListNode<T>::ListNode(constT&nItem,ListNode<T>*ptrNext):Date(nItem),ptrNext(ptrNext){}//返回指向后续结点的指针template<classT>ListNode<T>*ListNode<T>::NextListNode()const{returnptrNext;}template<classT>voidListNode<T>::InsertAfter(ListNode<T>*ptr){ptr->ptrNext=ptrNext;//将ptr的ptrNext指针指向本结点的后续结点
ptrNext=ptr;//本结点的ptrNext指针指向ptr}
template<classT>ListNode<T>*ListNode<T>::DeleteAfter(){ListNode<T>*ptrTemp=ptrNext;if(ptrNext==NULL)//处理本结点为尾结点时的情况
returnNULL;ptrNext=ptrTemp->ptrNext;//一般情况
returnptrTemp;}//链表类构造函数,4个私有指针成员设置为空,链表初始长度设置为0,初始当前结点//初始位置为-1template<classT>LinkedList<T>::LinkedList(void):ptrFront(NULL),ptrTail(NULL),ptrPrev(NULL),ptrCurr(NULL),nListLength(0),nPosition(-1){}//重载″=″号运算符template<classT>LinkedList<T>&LinkedList<T>::operator=(constLinkedList<T>&list){
if(this!=&list){DeleteAll();CopyList(list);}return*this;}//拷贝构造函数template<classT>LinkedList<T>::LinkedList(constLinkedList<T>&list){CopyList(list);}//重新设置当前指针的位置template<classT>voidLinkedList<T>::Reset(intnPos){intnStartPos;
if(!ptrFront)//如果当前指针为空,链表为空直接返回
{return;}if(nPos>=nListLength||nPos<0)//位置越界检查
{cerr<<″InvalidPosition!″<<endl;return;}if(nPos==0)//置当前指针为头结点
{ptrPrev=NULL;ptrCurr=ptrFront;nPosition=0;}else//一般情况
{ptrCurr=ptrFront->NextListNode();ptrPrev=ptrFront;nStartPos=1;for(nPosition=nStartPos;nPosition!=nPos;nPosition++)
//寻找该位置并使当前指针指向该位置{ptrPrev=ptrCurr;ptrCurr=ptrCurr->NextListNode();}}}//当前指针指向当前结点的后续结点template<classT>voidLinkedList<T>::Next(){if(ptrCurr){ptrPrev=ptrCurr;ptrCurr=ptrCurr->NextListNode();nPosition++;}}//将数据为nItem的结点插入到链表头template<classT>
voidLinkedList<T>::InsertFront(constT&nItem){ListNode<T>*newListNode=GetListNode(nItem);//获得一个封装有该数据 //的结点newListNode->SetNext(ptrFront);ptrFront=newListNode;nListLength++;}//将数据为nItem的结点插入到链表尾template<classT>voidLinkedList<T>::InsertTail(constT&nItem){ListNode<T>*newListNode;if(ptrCurr==NULL)InsertFront(nItem);//假设链表为空,使之成为头结点 //(也是尾结点)else//一般情况{while(ptrCurr->NextListNode())//寻找尾结点ptrCurr=ptrCurr->NextListNode(); newListNode=GetListNode(nItem);ptrCurr->InsertAfter(newListNode);}}//将数据为nItem的结点插入到链表的当前位置之前template<classT>voidLinkedList<T>::InsertAt(constT&nItem){ListNode<T>*newListNode;if(!ptrPrev)//插入到头结点
{newListNode=GetListNode(nItem,ptrFront);newListNode->SetNext(ptrFront);ptrFront=newListNode;
nListLength++;}else//一般情况
{
newListNode=GetListNode(nItem);ptrPrev->InsertAfter(newListNode);}if(ptrPrev==ptrTail){ptrTail=newListNode;nPosition=nListLength;}ptrCurr=newListNode;
}//将数据为nItem的结点插入到链表当前结点之后template<classT>voidLinkedList<T>::InsertAfter(constT&nItem){ListNode<T>*newListNode;if(!ptrCurr)//处理空链表的情况
{
newListNode=GetListNode(nItem);ptrCurr=newListNode;ptrFront=ptrCurr;}else//一般情况
{newListNode=GetListNode(nItem);ptrCurr->InsertAfter(newListNode);}if(ptrPrev==ptrTail){ptrTail=newListNode;nPosition=nListLength;}ptrCurr=newListNode;nListLength++;}//删除链表中的当前结点template<classT>voidLinkedList<T>::DeleteCurr()
{ListNode<T>*ptr;if(!ptrCurr)//处理空链表的情况
{cerr<<″TheListisempty!″<<endl;exit(1);}if(!ptrPrev)//删除头结点的情况
{ptr=ptrFront;ptrFront=ptrFront->NextListNode();}else//一般情况
ptr=ptrPrev->DeleteAfter();if(ptr==ptrTail){ptrTail=ptrPrev;nPosition--;}ptrCurr=ptr->NextListNode();FreeListNode(ptr);
nListLength--;}//删除链表中所有结点并释放资源template<classT>voidLinkedList<T>::DeleteAll(){ListNode<T>*ptrCurrPos,*ptrNextPos;ptrCurrPos=ptrFront;while(ptrCurrPos)//循环处理删除链表中的各个结点
{ptrNextPos=ptrCurrPos->NextListNode();FreeListNode(ptrCurrPos);ptrCurrPos=ptrNextPos;}ptrFront=NULL;ptrTail=NULL;ptrPrev=NULL;ptrCurr=NULL;
nListLength=0;nPosition=-1;}//删除链表的头结点template<classT>intLinkedList<T>::DeleteHead(){ListNode<T>*ptr=ptrFront;if(ptrFront){ptrFront=ptrFront->NextListNode();deleteptr;nListLength--;return1;}else//处理链表为空的情况
{cout<<″TheListisempty!″<<endl;return0;}}
//获得链表中当前结点的数据template<classT>T&LinkedList<T>::GetDate(){if(nListLength==0||!ptrCurr)//空链表的处理{cerr<<″Invalid!″<<endl;exit(1);}returnptrCurr->ShowDate();}//逐项拷贝链表中的各个结点template<classT>voidLinkedList<T>::CopyList(constLinkedList<T>&list){ListNode<T>*ptr=list.ptrFront;ptrCurr=NULL;while(ptr)//遍历list并创立新链表 {InsertAfter(ptr->ShowDate());ptr=ptr->NextListNode();}if(nPosition==-1)//list为空
return;ptrPrev=NULL;ptrCurr=ptrFront;for(intnPos=0;nPos!=list.CurrPosition();nPos++)
//将新链表的各个数据成员设置与原链表相同
{ptrPrev=ptrCurr;ptrCurr=ptrCurr->NextListNode();}nPosition=nPos;nListLength=list.ListLength();}
//获得下一个新结点,返回新结点地址template<classT>ListNode<T>*LinkedList<T>::GetListNode(constT&nItem,ListNode<T>*preNext){ListNode<T>*newListNode;newListNode=newListNode<T>(nItem,preNext);if(!newListNode){cerr<<″Memoryallocationfailure!″<<endl;exit(1);}returnnewListNode;}//输出链表中的各个结点数据template<classT>voidLinkedList<T>::DisplayList(){ptrCurr=ptrFront;while(ptrCurr)//遍历链表
{cout<<ptrCurr->ShowDate()<<endl;
ptrCurr=ptrCurr->NextListNode();}}//在链表中查找数据template<classT>intLinkedList<T>::Find(T&nItem){ptrCurr=ptrFront;ptrPrev=NULL;while(ptrCurr){if(ptrCurr->ShowDate()==nItem)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能温室大棚设计与管理方案
- 公司文化建设与员工培训方案
- 物业服务合同条款及范本解读
- 电工安全操作技术流程及记录样本
- 2026年提升房地产从业人员法律风险意识的方法
- 2025年中级西式面点师试题库(含答案解析)
- 客户投诉处理流程及案例分析报告
- 2026年自动化系统在建筑环境中的应用
- 伦理教育与实践融合-洞察及研究
- (2025年)德宏傣族景颇族自治州公开遴选公务员笔试题及答案解析(A类)
- 塔司、信号工安全晨会(班前会)
- 《电力建设安全工作规程》-第1部分火力发电厂
- 2024全国职业院校技能大赛ZZ060母婴照护赛项规程+赛题
- 回顾性临床研究的设计和分析
- 配电一二次融合技术的发展应用
- 钢板铺设安全施工方案
- 八年级物理上册期末测试试卷-附带答案
- 硬件设计与可靠性
- 垃圾渗滤液处理站运维及渗滤液处理投标方案(技术标)
- 经纬度丛书 秦制两千年:封建帝王的权力规则
- ppt素材模板超级玛丽
评论
0/150
提交评论