实验4友元函数及虚函数的应用

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实验4友元函数及虚函数的应用实验4友元函数及虚函数的应用4.1实验目的1.掌握友元函数的定义方法2.理解并掌握利用虚函数实现动态多态性和编写通用程序的方法3.掌握静态数据成员的特性4.2实验内容与步骤1.上机实验题一利用虚函数实现的多态性来求四种几何图形的面积之和。这四种几何图形是:三角形、矩形、正方形和圆。几何图形的类型可以通过构造函数或通过成员函数来设置。⑴分析计算这四种几何图的面积公式分别是:三角形的边长为W,高为H时,则三角形的面积为W*H/2;矩形的边长为W,宽为H时,则其面积为W*H;正方形的边长为S,则正方形的面积为S*S;圆的半径为R,其面积为3.1415926*R*R。为设置几何图形的数据并求出几何图形的面积,需要定义一个包含两个虚函数的类:classShape{public:virtualfloatArea(void)=0;//求面积virtualvoidSetdata(float,float=0)=0;//设置图形数据};因面积的计算依赖于几何图形,故在类中只能定义一个纯虚函数Area。同理,设置几何图形数据的函数Setdata也只能定义为虚函数。把这个基类派生出其它几何图形类。如派生出的三角形类为:classTriangle:publicShape{floatW,H;//三角形边长为W,高为Hpublic:Triangle(floatw=0,floath=0){W=w;H=h;}floatArea(void){returnW*H/2;}voidSetdata(floatw,floath=0){W=w;H=h;}};在派生类中定义了基类中两个虚函数的实现。为了实现求面积和设置数据的多态性,必C++面向对象程序设计实验指导须定义一个类,该类中定义一个指向基类Shape的指针数组,其元素分别指向由基类Shape派生出的不同的几何图形类,并完成求出所有几何图形面积之和,以及设置参数的函数。一个完整的参考程序如下:#includeiostream.h#includestring.hclassShape{public:virtualfloatArea(void)=0;//虚函数virtualvoidSetdata(float,float=0)=0;//虚函数};classTriangle:publicShape{floatW,H;//三角形边长为W,高为Hpublic:Triangle(floatw=0,floath=0){W=w;H=h;}floatArea(void)//定义虚函数{returnW*H/2;}voidSetdata(floatw,floath=0)//定义虚函数{W=w;H=h;}};classRectangle:publicShape{floatW,H;//矩形边长为W,高为Hpublic:Rectangle(floatw=0,floath=0){W=w;H=h;}floatArea(void)//定义虚函数{returnW*H;}voidSetdata(floatw,floath=0)//定义虚函数{W=w;H=h;}};实验4友元函数及虚函数的应用classSquare:publicShape{floatS;//正方形边长Spublic:Square(floata=0){S=a;}floatArea(void)//定义虚函数{returnS*S/2;}voidSetdata(floatw,floath=0)//定义虚函数{S=w;}};classCircle:publicShape{floatR;//圆的半径为Rpublic:Circle(floatr=0){R=r;}floatArea(void)//定义虚函数{return3.1415926*R*R;}voidSetdata(floatw,floath=0)//定义虚函数{R=w;}};classCompute{Shape**s;//指向基类的指针数组public:Compute(){//给几何图形设置参数s=newShape*[4];s[0]=newTriangle(3,4);C++面向对象程序设计实验指导s[1]=newRectangle(6,8);s[2]=newSquare(6.5);s[3]=newCircle(5.5);}floatSumArea(void);~Compute();voidSetdata(intn,floata,floatb=0)//A{s[n]-Setdata(a,b);}//B};Compute::~Compute()//释放动态分配的存储空间{for(inti=0;i4;i++)deletes[i];delete[]s;}floatCompute::SumArea(void){floatsum=0;for(inti=0;i4;i++)sum+=s[i]-Area();//通过基类指针实现多态性returnsum;}voidmain(void){Computea;cout四种几何图形的面积=a.SumArea()'\n';a.Setdata(2,10);//设置正方形的边长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行通过基类指针实现多态性。⑵上机要求实验4友元函数及虚函数的应用自己设计测试数据,测试程序的正确性。⑶写出实验报告。2.上机实验题二利用虚函数实现多态性,设计一个通用的双向链表操作程序。链表上每一个结点数据包括:姓名,地址和工资。要求建立一条双向有序链表,结点数据按工资从小到大的顺序排序。⑴分析首先定义抽象类Object,并由其派生出包含题目要求的结点数据。这两个派生类可定义为:classObject{//定义一个抽象类,用于派生描述结点信息的类public:Object(){}//缺省构造函数virtualintIsEqual(Object&)=0;//判两个结点是否相等virtualvoidShow()=0;//输出一个结点上的数据virtualintIsGreat(Object&)=0;//判两个结点的大小virtual~Object(){};};classMenNode:publicObject{//由抽象类派生出描述结点数据的类char*Name;//姓名char*Addr;//地址intSalary;//工资public:MenNode(charn=0,chara=0,inys=0){//完成数据初始化if(n==0)Name=0;else{Name=newchar[strlen(n)+1];strcpy(Name,n);}if(a==0)Addr=0;else{Addr=newchar[strlen(a)+1];strcpy(Addr,a);}Salary=s;}voidSetData(char*,char*,int);//重新设置结点的数据intIsEqual(Object&);//判二个结点是否相等intIsGreat(Object&ob);//判ob结点是否大于当前结点~MenNode()//释放动态分配的存储空间{if(Name)delete[]Name;if(Addr)delete[]Addr;}C++面向对象程序设计实验指导voidShow()//重新定义虚函数{cout姓名:Name'\t'地址:Addr'\t'工资:Salary'\n';}};产生一个新结点时,首先要在链表上找到插入位置(按工资大小的升序),然后将新结点插入。List类的定义参见教材。完成插入的成员函数为:voidList::AddNode(Node*node){if(Head==0){//AHead=Tail=node;//使链表首和链表尾指针都指向这结点node-Next=node-Prev=0;//指该结点的前后向指针置为空}else{//链表不为空,找到插入位置Node*pn=Head;while(pn){//BObject&obj=*(node-Info);if(pn-Info-IsGreat(obj)=0)break;//Celsepn=pn-Next;}if(pn==0){//DTail-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指向结点的前一个结点指向nodenode-Next=pn;node-Prev=pn;//设置后向链pn-Prev=node;}实验4友元函数及虚函数的应用}}}A行中条件成立时,双向链表为空链,要插入结点为链表上的第上一个结点,初始化这个双向链表。B行中的循环语句实现查找插入位置,当找到插入位置或整个链表上的结点都查完后,结束这个循环语句。C行中的条件成立时,表示要把结点插在pn所指向的结点之前。D行中的条件成立时,表示要把结点插入链尾。若E行中的条件成立时,要把结点插在第一个结点之前;否则将结点插在pn所指向的结点之前。一个完整的参考程序如下:#includeiostream.h#includestring.hclassObject{//定义一个用于派生结点信息的抽象类public:Object(){}virtualintIsEqual(Object&)=0;//判二个结点是否相等virtualvoidShow()=0;//输出一个结点上的数据virtualintIsGreat(Object&)=0;//判二个结点的大小virtual~Object(){};};classNode{//结点类private:Object*Info;//指向描述结点的数据域Node*Prev,*Next;//用于构成链表的前后向指针public:Node(){Info=0;Prev=0;Next=0;}Node(Node&node)//完成拷贝功能的构造函数{Info=node.Info;Prev=node.Prev;Next=node.Next;}voidFillInfo(Object*obj){Info=obj;}//使Info指向数据域friendclassList;//定义友元类};classList{//实现双向链表操作的类Node*Head,*Tail;//链表首和链表尾指针public:List(){Head=Tail=0;}//置为空链表~List(){DeleteList();}//释放链表占用的存储空间voidAddNode(Node*);//在链表尾加一个结点Node*DeleteNode(Node*);//删除链表中的一个指定的结点C++面向对象程序设计实验指导Node*LookUp(Object&);//在链表中查找一个指定的结点voidShowList();//输出整条链表上的数据voidDeleteList();//删除整条链表};voidList::AddNode(Node*node){if(Head==0){//条件成立时,为空链表Head=Tail=node;//使

1 / 12
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功