chap9-C++课件-清华大学郑莉.ppt
《chap9-C++课件-清华大学郑莉.ppt》由会员分享,可在线阅读,更多相关《chap9-C++课件-清华大学郑莉.ppt(81页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C+语言程序设计清华大学 郑莉2本章主要内容本章主要内容l模板模板l群体类群体类l群体数据的组织群体数据的组织C+语言程序设计清华大学 郑莉3第一部分第一部分模板模板l函数模板函数模板l类模板类模板C+语言程序设计清华大学 郑莉4函数模板函数模板l函数模板可以用来创建一个通用功能函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一的函数,以支持多种不同形参,进一步简化重载函数的函数体设计。步简化重载函数的函数体设计。l声明方法:声明方法:template 函数声明 函 数 模 板C+语言程序设计清华大学 郑莉5求绝对值函数的模板求绝对值函数的模板#includeusing name
2、space std;templateT abs(T x) return x0?-x:x; int main() int n=-5; double d=-5.5; coutabs(n)endl; coutabs(d)endl; 函 数 模 板运行结果:运行结果:55.5C+语言程序设计清华大学 郑莉6求绝对值函数的模板分析求绝对值函数的模板分析l编译器从调用编译器从调用abs()时实参的类型,推时实参的类型,推导出函数模板的类型参数。例如,对导出函数模板的类型参数。例如,对于调用表达式于调用表达式abs(n),由于实参,由于实参n为为int型,所以推导出模板中类型参数型,所以推导出模板中类型参数
3、T为为int。l当类型参数的含义确定后,编译器将当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数:以函数模板为样板,生成一个函数:int abs(int x) return x0?-x:x; 函 数 模 板C+语言程序设计清华大学 郑莉7类模板的作用类模板的作用使用类模板使用户可以为类声明一使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本的返回值,能取任意类型(包括基本类型的和用户自定义类型)。类型的和用户自定义类型)。类 模 板C+语言程
4、序设计清华大学 郑莉8类模板的声明类模板的声明l类模板:类模板:template class 类名类成员声明l如果需要在类模板以外定义其成员如果需要在类模板以外定义其成员函数,则要采用以下的形式:函数,则要采用以下的形式:template 类型名 类名:函数名(参数表)类 模 板C+语言程序设计清华大学 郑莉9例例9-2 类模板应用举例类模板应用举例#include #include using namespace std;/ 结构体结构体Studentstruct Student int id; /学号学号 float gpa; /平均分平均分; 类 模 板template /类模板:实现对
5、任意类型数据进行存取类模板:实现对任意类型数据进行存取class Store private: T item; / 用于存放任意类型的数据用于存放任意类型的数据 int haveValue; / 用于标记用于标记item是否已被存入内容是否已被存入内容 public: Store(void); / 默认形式(无形参)的构造函数默认形式(无形参)的构造函数 T GetElem(void); /提取数据函数提取数据函数 void PutElem(T x); /存入数据函数存入数据函数;/ 默认形式构造函数的实现默认形式构造函数的实现template Store:Store(void): haveV
6、alue(0) 10template / 提取数据函数的实现提取数据函数的实现T Store:GetElem(void) / 如果试图提取未初始化的数据,则终止程序如果试图提取未初始化的数据,则终止程序 if (haveValue = 0) cout No item present! endl; exit(1); return item; / 返回返回item中存放的数据中存放的数据 template / 存入数据函数的实现存入数据函数的实现 void Store:PutElem(T x) haveValue+; / 将将haveValue 置为置为 TRUE,表示,表示item中已存入数值中
7、已存入数值 item = x; / 将将x值存入值存入item11int main() Student g= 1000, 23; Store S1, S2; Store S3; Store D; S1.PutElem(3); S2.PutElem(-7); cout S1.GetElem() S2.GetElem() endl; S3.PutElem(g); cout The student id is S3.GetElem().id endl; cout Retrieving object D ;cout D.GetElem() endl; /输出对象输出对象D的数据成员的数据成员/ 由于由
8、于D未经初始化未经初始化,在执行函数在执行函数D.GetElement()时出错时出错12C+语言程序设计清华大学 郑莉13第二部分第二部分群体数据群体数据l线性群体线性群体 线性群体的概念 直接访问群体-数组类 顺序访问群体-链表类 栈类 队列类C+语言程序设计清华大学 郑莉14群体的概念群体的概念群体群体是指由多个数据元素组成的集是指由多个数据元素组成的集合体。群体可以分为两个大类:合体。群体可以分为两个大类:线性群线性群体体和和非线性群体非线性群体。线性群体中的元素按位置排列有序,线性群体中的元素按位置排列有序,可以区分为第一个元素、第二个元素等。可以区分为第一个元素、第二个元素等。非线
9、性群体不用位置顺序来标识元非线性群体不用位置顺序来标识元素。素。C+语言程序设计清华大学 郑莉15线性群体的概念线性群体的概念线性群体中的元素次序与其位置关线性群体中的元素次序与其位置关系是对应的。在线性群体中,又可按照系是对应的。在线性群体中,又可按照访问元素的不同方法分为访问元素的不同方法分为直接访问直接访问、顺顺序访问序访问和和索引访问索引访问。在本章我们只介绍直接访问和顺序在本章我们只介绍直接访问和顺序访问。访问。第一个元素第二个元素第三个元素最后一个元素C+语言程序设计清华大学 郑莉16数组数组l静态数组是具有固定元素个数的群体,其静态数组是具有固定元素个数的群体,其中的元素可以通过
10、下标直接访问。中的元素可以通过下标直接访问。 缺点:大小在编译时就已经确定,在运行时无法修改。l动态数组由一系列位置连续的,任意数量动态数组由一系列位置连续的,任意数量相同类型的元素组成。相同类型的元素组成。 优点:其元素个数可在程序运行时改变。l动态数组类模板:例动态数组类模板:例9-3(9_3.h)直接访问的线性群体#ifndef ARRAY_CLASS#define ARRAY_CLASSusing namespace std;#include #include #ifndef NULLconst int NULL = 0;#endif / NULLenum ErrorType inva
11、lidArraySize, memoryAllocationError, indexOutOfRange ;char *errorMsg = Invalid array size, Memory allocation error, Invalid index: ;动态数组类模板程序17template class Array private: T* alist; int size; void Error(ErrorType error,int badIndex=0) const; public: Array(int sz = 50); Array(const Array& A); Array(
12、void); Array& operator= (const Array& rhs); T& operator(int i); operator T* (void) const; int ListSize(void) const; void Resize(int sz); ;18C+语言程序设计清华大学 郑莉19数组类模板的构造函数数组类模板的构造函数/ 构造函数构造函数template Array:Array(int sz) if (sz = 0) /sz为数组大小(元素个数),若小于为数组大小(元素个数),若小于0,则输出错误信息,则输出错误信息 Error(invalidArraySiz
13、e); size = sz; / 将元素个数赋值给变量将元素个数赋值给变量size alist = new Tsize; /动态分配动态分配size个个T类型的元素空间类型的元素空间 if (alist = NULL) /如果分配内存不成功,输出错误信息如果分配内存不成功,输出错误信息 Error(memoryAllocationError);直接访问的线性群体C+语言程序设计清华大学 郑莉20数组类的拷贝构造函数数组类的拷贝构造函数template Array:Array(const Array& X) int n = X.size; size = n; alist = new Tn; if
14、 (alist = NULL) Error(memoryAllocationError); T* srcptr = X.alist; / X.alist是对象是对象X的数组首地址的数组首地址 T* destptr = alist; / alist是本对象中的数组首地址是本对象中的数组首地址 while (n-) / 逐个复制数组元素逐个复制数组元素 *destptr+ = *srcptr+;直接访问的线性群体C+语言程序设计清华大学 郑莉21浅拷贝浅拷贝 alist sizeAA的数组元素占用的内存拷贝前 alist sizeAA的数组元素占用的内存拷贝后 alist sizeBint mai
15、n() Array A(10); . Array B(A); .template Array:Array( const Array& X) size = X.size; alist= X.alist;C+语言程序设计清华大学 郑莉22深拷贝深拷贝 alist sizeAA的数组元素占用的内存拷贝前 alist sizeAA的数组元素占用的内存拷贝后 alist sizeBB的数组元素占用的内存C+语言程序设计清华大学 郑莉23数组类的重载数组类的重载=运算符函数运算符函数template Array& Array:operator= (const Array& rhs) int n = rhs
16、.size; if (size != n) delete alist; alist = new Tn; if (alist = NULL) Error(memoryAllocationError); size = n; T* destptr = alist; T* srcptr = rhs.alist; while (n-) *destptr+ = *srcptr+; return *this;直接访问的线性群体C+语言程序设计清华大学 郑莉24数组类的重载下标操作符函数数组类的重载下标操作符函数template T& Array:operator (int n) / 检查下标是否越界检查下标
17、是否越界 if (n size-1) Error(indexOutOfRange,n); / 返回下标为返回下标为n的数组元素的数组元素 return alistn;直接访问的线性群体C+语言程序设计清华大学 郑莉25为什么有的函数返回引用为什么有的函数返回引用l如果一个函数的返回值是一个对象的如果一个函数的返回值是一个对象的值,它就被认为是一个常量,不能成值,它就被认为是一个常量,不能成为左值。为左值。l如果返回值为引用。由于引用是对象如果返回值为引用。由于引用是对象的别名,所以通过引用当然可以改变的别名,所以通过引用当然可以改变对象的值。对象的值。直接访问的线性群体C+语言程序设计清华大学
18、 郑莉26重载指针转换操作符重载指针转换操作符template Array:operator T* (void) const / 返回当前对象中私有数组的首地址返回当前对象中私有数组的首地址 return alist;直接访问的线性群体C+语言程序设计清华大学 郑莉27指针转换运算符的作用指针转换运算符的作用#include using namespace std;int main() int a10; void read(int *p, int n); read(a, 10);void read(int *p, int n) for (int i=0; ipi;int main() Arra
19、y a(10); void read(int *p, n); read(a, 10);void read(int *p, int n) for (int i=0; ipi;直接访问的线性群体C+语言程序设计清华大学 郑莉28Array类的应用类的应用l例例9-4求范围求范围2N中的质数,中的质数,N在程序在程序运行时由键盘输入。运行时由键盘输入。直接访问的线性群体#include #include #include 9_3.husing namespace std;int main() Array A(10); int n; int primecount = 0, i, j; cout = 2
20、 as upper limit for prime numbers: ; cin n; Aprimecount+ = 2; / 2是一个质数是一个质数 for(i = 3; i n; i+) if (primecount = A.ListSize() A.Resize(primecount + 10); if (i % 2 = 0) continue; j = 3; while (j i/2) Aprimecount+ = i; for (i = 0; i primecount; i+) cout setw(5) Ai; if (i+1) % 10 = 0) cout endl; cout e
21、ndl;29C+语言程序设计清华大学 郑莉30链表链表l链表是一种动态数据结构,可以用来链表是一种动态数据结构,可以用来表示顺序访问的线性群体。表示顺序访问的线性群体。l链表是由系列链表是由系列结点结点组成的,结点可以组成的,结点可以在运行时动态生成。在运行时动态生成。l每一个结点包括每一个结点包括数据域数据域和指向链表中和指向链表中下一个结点的下一个结点的指针指针(即下一个结点的(即下一个结点的地址)。如果链表每个结点中只有一地址)。如果链表每个结点中只有一个指向后继结点的指针,则该链表称个指向后继结点的指针,则该链表称为单链表。为单链表。顺序访问的线性群体C+语言程序设计清华大学 郑莉31
22、单链表单链表 data1 data2 data3 datan NULLheadrear顺序访问的线性群体C+语言程序设计清华大学 郑莉32单链表的结点类模板单链表的结点类模板template class Node private: Node *next; public: T data; Node(const T& item,Node* ptrnext = NULL); void InsertAfter(Node *p); Node *DeleteAfter(void); Node *NextNode(void) const; 顺序访问的线性群体C+语言程序设计清华大学 郑莉33在结点之后插入一
23、个结点在结点之后插入一个结点 data1 data2 p datatemplate void Node:InsertAfter(Node *p) /p节点指针域指向当前节点的后继节点节点指针域指向当前节点的后继节点 p-next = next; next = p; /当前节点的指针域指向当前节点的指针域指向p 顺序访问的线性群体C+语言程序设计清华大学 郑莉34 删除结点之后的结点删除结点之后的结点顺序访问的线性群体 data1 data2 data3Node *Node:DeleteAfter(void) Node *tempPtr = next; if (next = NULL) retu
24、rn NULL; next = tempPtr-next; return tempPtr; tempPtrC+语言程序设计清华大学 郑莉35链表的基本操作链表的基本操作l生成结点生成结点l插入结点插入结点l查找结点查找结点l删除结点删除结点l遍历链表遍历链表l清空链表清空链表顺序访问的线性群体C+语言程序设计清华大学 郑莉36链表类模板链表类模板(例例9-6)/9_6.h#ifndef LINKEDLIST_CLASS#define LINKEDLIST_CLASS#include #include using namespace std;#ifndef NULLconst int NULL
25、= 0;#endif / NULL#include 9_5.h顺序访问的线性群体template class LinkedList private: Node *front, *rear; Node *prevPtr, *currPtr; int size; int position; Node *GetNode(const T& item, Node *ptrNext=NULL); void FreeNode(Node *p); void CopyList(const LinkedList& L);37 public: LinkedList(void); LinkedList(const L
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- chap9 C+ 课件 清华大学
限制150内