实验4友元函数及虚函数的应用_第1页
实验4友元函数及虚函数的应用_第2页
实验4友元函数及虚函数的应用_第3页
实验4友元函数及虚函数的应用_第4页
实验4友元函数及虚函数的应用_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

1、实验4 友元函数及虚函数的应用4.1实验目的1.掌握友元函数的定义方法2.理解并掌握利用虚函数实现动态多态性和编写通用程序的方法3.掌握静态数据成员的特性4.2实验内容与步骤1.上机实验题一 利用虚函数实现的多态性来求四种几何图形的面积之和。这四种几何图形是:三角形、矩形、正方形和圆。几何图形的类型可以通过构造函数或通过成员函数来设置。分析 计算这四种几何图的面积公式分别是:三角形的边长为W,高为H时,则三角形的面积为W* H/2;矩形的边长为W,宽为H时,则其面积为W* H;正方形的边长为S,则正方形的面积为S*S;圆的半径为R,其面积为 3. *R *R。为设置几何图形的数据并求出几何图形

2、的面积,需要定义一个包含两个虚函数的类:class Shapepublic:virtual float Area( void) =0;/求面积virtual void Setdata(float ,float =0) =0;/设置图形数据;因面积的计算依赖于几何图形,故在类中只能定义一个纯虚函数Area。同理,设置几何图形数据的函数Setdata也只能定义为虚函数。把这个基类派生出其它几何图形类。如派生出的三角形类为:class Triangle:public Shape float W,H;/三角形边长为W,高为Hpublic:Triangle(float w=0,float h=0) W=

3、w; H = h; float Area( void) return W*H/2; void Setdata(float w,float h=0) W=w; H = h; ;在派生类中定义了基类中两个虚函数的实现。为了实现求面积和设置数据的多态性,必须定义一个类,该类中定义一个指向基类Shape的指针数组,其元素分别指向由基类Shape派生出的不同的几何图形类,并完成求出所有几何图形面积之和,以及设置参数的函数。一个完整的参考程序如下:#include #include class Shapepublic:virtual float Area( void) =0;/虚函数virtual voi

4、d Setdata(float ,float =0) =0;/虚函数;class Triangle:public Shapefloat W,H;/三角形边长为W,高为Hpublic:Triangle(float w=0,float h=0)W=w;H = h; float Area( void)/定义虚函数 return W*H/2; void Setdata(float w,float h=0)/定义虚函数 W=w; H = h; ;class Rectangle:public Shapefloat W,H;/矩形边长为W,高为Hpublic:Rectangle(float w=0,floa

5、t h=0) W=w; H = h; float Area( void)/定义虚函数return W*H; void Setdata(float w,float h=0)/定义虚函数 W=w; H = h;class Square:public Shapefloat S;/正方形边长Spublic:Square(float a=0) S=a; float Area( void) /定义虚函数return S*S/2; void Setdata(float w,float h=0)/定义虚函数S=w; ;class Circle:public Shapefloat R;/圆的半径为Rpublic

6、:Circle(float r=0) R=r; float Area( void)/定义虚函数return 3.*R *R ; void Setdata(float w,float h=0)/定义虚函数R=w; ;class ComputeShape *s;/指向基类的指针数组public: Compute() /给几何图形设置参数s= new Shape *4;s0 = new Triangle(3,4);s1 = new Rectangle(6,8);s2 = new Square(6.5);s3 = new Circle(5.5);float SumArea(void ) ;Comput

7、e();void Setdata(int n, float a,float b=0) /A sn-Setdata(a,b); /B;Compute:Compute()/释放动态分配的存储空间for(int i= 0; i4; i+)delete si;delete s;float Compute:SumArea(void )float sum =0;for( int i =0; iArea();/通过基类指针实现多态性return sum;void main(void ) Compute a;cout四种几何图形的面积=a.SumArea()n;a.Setdata(2,10);/设置正方形的边

8、长cout四种几何图形的面积=a.SumArea()n; a.Setdata(0, 10,12); /设置三角形的边长和高cout四种几何图形的面积=a.SumArea()n;a.Setdata(1,2,5);/设置正方形的长和宽cout四种几何图形的面积=a.SumArea()n;a.Setdata(3,15.5);cout四种几何图形的面积=a.SumArea()n;程序中A行的Setdata函数属于函数重载,它不是虚函数。该函数中的B行通过基类指针实现多态性。上机要求自己设计测试数据,测试程序的正确性。写出实验报告。2.上机实验题二利用虚函数实现多态性,设计一个通用的双向链表操作程序。链

9、表上每一个结点数据包括:姓名,地址和工资。要求建立一条双向有序链表,结点数据按工资从小到大的顺序排序。分析 首先定义抽象类Object,并由其派生出包含题目要求的结点数据。这两个派生类可定义为:class Object/定义一个抽象类,用于派生描述结点信息的类public:Object() /缺省构造函数virtual int IsEqual(Object &)=0;/判两个结点是否相等virtual void Show()=0;/输出一个结点上的数据virtual int IsGreat(Object &)=0;/判两个结点的大小virtual Object() ;class MenNode

10、:public Object/由抽象类派生出描述结点数据的类char *Name;/姓名char *Addr;/地址int Salary;/工资public:MenNode(char n =0, char a=0, iny s =0) /完成数据初始化if( n=0 ) Name =0;else Name = new char strlen(n)+1;strcpy(Name,n);if( a=0 ) Addr =0;else Addr = new char strlen(a)+1;strcpy(Addr,a);Salary =s;void SetData(char * ,char *, int

11、 );/重新设置结点的数据int IsEqual(Object &);/判二个结点是否相等int IsGreat(Object &ob);/判ob结点是否大于当前结点MenNode( )/释放动态分配的存储空间if(Name) delete Name; if( Addr) delete Addr;void Show()/重新定义虚函数 cout 姓名: Namet 地址:Addrt工资:SalaryNext=node-Prev=0;/指该结点的前后向指针置为空else /链表不为空,找到插入位置Node *pn = Head;while (pn ) /B Object &obj= *(node

12、-Info);if( pn-Info-IsGreat( obj) Next;if(pn = 0 ) /D Tail-Next=node;/使原链表尾结点的后向指针指向这结点 node-Prev=Tail;/使该结点的前向指针指向原链表尾结点 Tail=node;/使Tail指向新的链表尾结点 node-Next=0;else /插在pn所指向结点之前if( pn = Head )/Enode-Next = Head;Head-Prev = node;node-Prev = 0;Head = node;else /Fpn-Prev-Next = node;/使pn指向结点的前一个结点指向node

13、 node-Next = pn; node-Prev = pn;/设置后向链 pn-Prev = node;A行中条件成立时,双向链表为空链,要插入结点为链表上的第上一个结点,初始化这个双向链表。B行中的循环语句实现查找插入位置,当找到插入位置或整个链表上的结点都查完后,结束这个循环语句。C行中的条件成立时,表示要把结点插在pn所指向的结点之前。D行中的条件成立时,表示要把结点插入链尾。若E行中的条件成立时,要把结点插在第一个结点之前;否则将结点插在pn所指向的结点之前。一个完整的参考程序如下:#include #include class Object/定义一个用于派生结点信息的抽象类pub

14、lic:Object() virtual int IsEqual(Object &)=0;/判二个结点是否相等virtual void Show()=0;/输出一个结点上的数据virtual int IsGreat(Object &)=0; /判二个结点的大小virtual Object() ;class Node/结点类private:Object *Info;/指向描述结点的数据域Node *Prev,*Next;/用于构成链表的前后向指针public: Node () Info=0; Prev=0; Next=0;Node ( Node &node)/完成拷贝功能的构造函数Info=no

15、de.Info;Prev=node.Prev;Next=node.Next; void FillInfo(Object *obj)Info =obj;/使Info指向数据域friend class List;/定义友元类;class List/实现双向链表操作的类Node *Head,*Tail;/链表首和链表尾指针public:List()Head=Tail=0;/置为空链表List()DeleteList();/释放链表占用的存储空间void AddNode(Node *);/在链表尾加一个结点Node * DeleteNode(Node *);/删除链表中的一个指定的结点Node *Lo

16、okUp(Object &);/在链表中查找一个指定的结点void ShowList();/输出整条链表上的数据void DeleteList();/删除整条链表;void List:AddNode(Node *node)if(Head =0)/条件成立时,为空链表Head=Tail=node;/使链表首和链表尾指针都指向这结点node-Next=node-Prev=0;/指该结点的前后向指针置为空else /链表不为空,找到插入位置Node *pn = Head;while (pn ) Object &obj= *(node-Info);if( pn-Info-IsGreat( obj) N

17、ext;if(pn = 0 ) /插入链尾 Tail-Next=node;/使原链表尾结点的后向指针指向这结点 node-Prev=Tail;/使该结点的前向指针指向原链表尾结点 Tail=node;/使Tail指向新的链表尾结点 node-Next=0;else /插在pn所指向结点之前if( pn = Head ) /插在第一个结点之前node-Next = Head; Head-Prev = node;node-Prev = 0; Head = node;else/使pn指向结点的前一个结点指向node pn-Prev-Next = node; node-Next = pn; node-

18、Prev = pn;/设置后向链 pn-Prev = node;Node * List:DeleteNode(Node *node)/删除指定的结点if( node = Head )/二者相等,表示删除链表首结点if(node = Tail)/二者相等,表示链表上只有一个结点Head=Tail=0;else /删除链表首结点Head=node-Next;Head-Prev=0;else /删除的结点不是链表上的首结点 node-Prev-Next=node-Next;/从后向链指针上取下该结点 if(node != Tail ) node-Next-Prev=node-Prev; else T

19、ail = node-Prev ;/要删除的结点为链表尾结点node-Prev=node-Next=0;/将已删除结点的前后向指针置为空return( node);Node * List:LookUp(Object &obj)/从链表上查找一个结点Node *pn=Head;while(pn) if(pn-Info-IsEqual(obj) return pn;/找到要找的结点pn=pn-Next;return 0;/链表上没有要找的结点void List :ShowList()/输出链表上各结点的数据值Node *p=Head;while(p) p-Info-Show();p=p-Next;

20、void List:DeleteList()/删除整条链表Node *p,*q;p=Head;while (p) delete p-Info;/释放描述结点数据的动态空间q=p; p=p-Next;delete q;/释放Node占用的动态空间class MenNode :public Object/由抽象类派生出描述结点数据的类char *Name;/姓名char *Addr;/地址int Salary;/工资public:MenNode(char *n=0, char *a=0, int s =0) if( n=0 ) Name =0;else Name = new char strlen

21、(n)+1;strcpy(Name,n);if( a=0 ) Addr =0;else Addr = new char strlen(a)+1;strcpy(Addr,a);Salary =s;void SetData(char * ,char *, int );int IsEqual(Object &);int IsGreat(Object &);MenNode( )if(Name) delete Name;if( Addr) delete Addr;void Show()/重新定义虚函数 cout 姓名: Namet 地址:Addrt 工资:Salaryn;void MenNode:Set

22、Data(char *n ,char *a, int s)if(Name) delete Name;if(Addr) delete Addr;if( n=0 ) Name =0;else Name = new char strlen(n)+1;strcpy(Name,n);if( a=0 ) Addr =0;else Addr = new char strlen(a)+1;strcpy(Addr,a);Salary =s;int MenNode:IsEqual(Object &obj)/定义比较结点是否相等的虚函数MenNode &temp=(MenNode &) obj;return (Salary =

温馨提示

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

评论

0/150

提交评论