c++派生类与继承实验报告材料.docx
- 文档编号:28070274
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:25
- 大小:133.25KB
c++派生类与继承实验报告材料.docx
《c++派生类与继承实验报告材料.docx》由会员分享,可在线阅读,更多相关《c++派生类与继承实验报告材料.docx(25页珍藏版)》请在冰豆网上搜索。
c++派生类与继承实验报告材料
实验2派生类与继承
实验课程名:
面向对象程序设计(C++)
专业班级:
学号:
姓名:
实验时间:
实验地点:
指导教师:
2.1实验目的和要求
(1)掌握派生类的声明方法和派生类构造函数的定义方法。
(2)掌握不同继承方式下,基类成员在派生类中的访问属性。
(3)掌握在继承方式下,构造函数与析构函数的执行顺序与构造规则。
(4)学习虚基类在解决二义性问题中的作用。
二、实验内容
一、构造一个类Geometry及其派生类,该类主要实现关于几何图形的基本操作。
对于基类“几何图形”,有求面积、求体积的函数(纯虚函数),其派生类圆和矩形主要有初始化(构造函数),求面积,求周长操作,类圆的派生类圆球和圆柱有求表面积、体积操作。
试在主函数中分别定义圆、圆球、圆柱以及矩形的对象,并调用其成员函数实现其相应操作。
实验代码如下:
#include
usingnamespacestd;
classGeometry
{
public:
Geometry(){}
~Geometry(){}
doubleGetArea(){}//求面积函数
doubleGetPerimeter(){}//求体积函数
doubleGetcolume(){}//求周长函数
virtualshow(){}
};
classCircle:
publicGeometry
{
public:
Circle(doublei)
{
radiums=i;
}
~Circle(){}
doubleGetArea();
doubleGetcolume();
doubleR()
{
returnradiums;
}
show();
private:
doubleradiums;
};
doubleCircle:
:
GetArea()
{
doubleS;
S=3.14*radiums*radiums;
returnS;
}
doubleCircle:
:
Getcolume()
{
doubleL;
L=2*3.14*radiums;
returnL;
}
Circle:
:
show()
{
cout<<"圆的面积为:
"< "< } classRectangle: publicGeometry { public: Rectangle(doublei,doublej){length=i;wide=j;} ~Rectangle(){} doubleGetArea(); doubleGetcolume(); doubleL() { returnlength; } show(); private: doublelength; doublewide; }; doubleRectangle: : GetArea() { doubleS; S=length*wide; returnS; } doubleRectangle: : Getcolume() { doubleL; L=2*(length+wide); returnL; } Rectangle: : show() { cout<<"矩形的面积为: "< "< } classBall: publicCircle { public: Ball(doublei): Circle(i){}; ~Ball(){}; doubleGetArea(); doubleGetPerimeter(); show(); }; doubleBall: : GetArea() { doubleS; S=4*3.14*R()*R(); returnS; }; doubleBall: : GetPerimeter() { doubleV; V=(4/3)*3.14*R()*R()*R(); returnV; } Ball: : show() { cout<<"球的体积为: "< "< } classColumn: publicCircle,publicRectangle { public: Column(doublei,doublej,doublek): Circle(i),Rectangle(j,k){}; ~Column(){}; doubleGetArea(); doubleGetPerimeter(); show(); }; doubleColumn: : GetArea() { return(2*3.14*R()*R()+2*3.14*R()*L()); } doubleColumn: : GetPerimeter() { return(3.14*R()*R()*L()); } Column: : show() { cout<<"圆柱的体积为: "< "< } intmain() { Circlecircle(2.5); circle.show(); Rectanglerectangle(3,4); rectangle.show(); Ballball(3.3); ball.show(); Columncolumn(1,2,3); column.show(); return0; } 运行结果: 代码分析: 1)首先定义基类Geometry,在定义基类的派生类Circle,Rectangle 再定义以Circle,Rectangle为基类的派生类Column,以及以Circle为基类的派生类Ball; 2)在定义派生类时用构造函数初始化私有成员; 3)最后用类的对象来调用类函数; 二、设计如下类: (1)建立一个Point类,表示平面中的一个点;建立一个Line类,表示平面中的一条线端,内含两个Point类的对象;建立Triangle类,表示一个三角形,内含三个Line类的对象构成一个三角形。 (2)设计三个类的相应的构造函数、复制构造函数,完成初始化和对象复制 (3)设计Triangle类的成员函数完成三条边是否能构成三角形的检验和三角形面积计算,面积显示。 实验代码: #include #include usingnamespacestd; classPoint//定义一个点的类,坐标为(x,y) { public: Point(doublei,doublej){x=i;y=j;} doublex,y; }; classLine { public: Line(doublex1,doubley1,doublex2,doubley2): p1(x1,y1),p2(x2,y2){}; doublelength(); private: Pointp1,p2; }; doubleLine: : length() { return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); } classTriangle { public: Triangle(doublex1,doubley1,doublex2,doubley2,doublex3,doubley3,doublex4,doubley4,doublex5,doubley5,doublex6,doubley6): L1(x1,y1,x2,y2),L2(x3,y3,x4,y4),L3(x5,y5,x6,y6){}; intpanduan(); doubleArea(); voidshow(); private: LineL1,L2,L3; }; intTriangle: : panduan() { doublea=L1.length(); doubleb=L2.length(); doublec=L3.length(); if(a+b>c&&b+c>a&&a+c>b) return1; else return0; } doubleTriangle: : Area() { doublea=L1.length(); doubleb=L2.length(); doublec=L3.length(); doubles=(a+b+c)/2; return(sqrt(s*(s-a)*(s-b)*(s-c))); } voidTriangle: : show() { if(panduan()) cout<<"三角形的面积为: "< else cout<<"不能构成三角形"< } intmain() { TriangleT1(0,0,0,1,0,0,1,0,0,1,1,0); TriangleT2(1,0,0,0,0,0,0,2,0,0,0,1); T1.show(); T2.show(); return0; } 实验结果: 实验分析: 1)在主函数中定义两个三角形的类,分别由三条边六个点组成,其中第一组能组成三角形,输出面积,第二组边不能组成三角形输出不能构成三角形; 2)定义点类时,定义两个浮点型数据,用来表示点的坐标,定义边类时定义两个顶点,表示两个端点组成线段,定义三角形类时,用三边表示三角形; 3)三角形的面积用海伦公式求得,在三角形中定义一个判断函数,判断三边能否组成三角形,当能组成三角形时则求面积并输出,当不能组成三角形时,输出不能构成三角形; 三、 定义一个基类MyArray,基类中可以存放一组整数,基类中有构造函数、析构函数、输入数据和输出数据的函数。 classMyArray{ public: MyArray(intleng); ~MyArray{}; voidInput(); voidDisplay(string); protected: int*alist; intlength; }; (1)声明一个类SortArray继承类MyArray,在该类中定义一个函数,具有将输入的整数从小到大进行排序的功能。 (2)声明一个类ReArray继承类MyArray,在该类中定义一个函数,具有将输入的整数进行倒置的功能。 (3)声明一个类AverArray继承类MyArray,在该类中定义一个函数,具有求输入的整数平均值的功能。 (4)声明一个NewArray类,同时继承了类SortArray,ReArray和AverArray,使得类NewArray的对象同时具有排序、倒置和求平均值的功能。 在继承的过程中声明MyArray为虚基类,体会虚基类在解决二义性问题中的作用。 实验代码: #include #include usingnamespacestd; classMyarray { protected: int*alist; intlength; public: Myarray(intlen) {alist=newint[len];length=len;} ~Myarray(){}; voidinput() { inti; for(i=0;i { cout<<"输入数组的第"< "<<'\n'; cin>>alist[i]; } } intgetlen(){returnlength;} voiddisplay() { for(inti=0;i cout< cout< } }; classSortArray: virtualpublicMyarray { public: SortArray(intn): Myarray(n){} sort() { inti,j,t; for(j=0;j { for(i=0;i { if(alist[i]>alist[i+1]) { t=alist[i]; alist[i]=alist[i+1]; alist[i+1]=t; } } } cout<<"排序后数组为: "; for(i=0;i { cout< } } }; classaverarray: virtualpublicMyarray { public: averarray(intn): Myarray(n){} floatgetaver() {floataver; intsum=0,i; for(i=0;i sum+=alist[i]; aver=(float)sum/length; returnaver; } }; classrearray: virtualpublicMyarray { public: rearray(intn): Myarray(n) {} voidturn() { inti,t,j=length-1; for(i=0;i { t=alist[i]; alist[i]=alist[j]; alist[j]=t; } } }; classnawarray: publicrearray,publicaverarray,publicSortArray { public: nawarray(intn): Myarray(n),rearray(n),averarray(n),SortArray(n) {} }; intmain() { nawarrayA(10); A.input(); A.display(); A.sort(); cout<<"输出平均值: "< cout< cout<<"倒置: "< A.turn(); A.display(); return0; } 实验结果: 结果分析: 定义一个基类,用指针作为数组名,定义一个数组,在定义各个基类,分别实现求平均值,排序,倒置的功能。 在调用成员时由于各个派生类都有基类的成员input,output,故用虚基类,避免出现二异性。 四、队列具有先进先出的特点,所有新来的元素都放在队列尾部,出队列的元素从队列头部出去。 栈具有后进先出的特点,所有入栈的元素都放在栈顶,出栈时栈顶元素先出。 这两种结构具有很多相似的地方: 都存放了一系列的元素,元素的操作都在两头进行,元素个数都是动态可变的。 我们可以设计一个基类,完成它们共同的功能,然后分别派生出队列类和栈类。 这样可以减少代码,提高效率。 设计的基类也可以用于派生出其他类。 本实验要求设计这个基类以及它的两个派生类。 设计基类LinkList,用链表结构实现。 要求链表类具有以下功能: •能够在链表的头尾增加节点以及在链表尾增加节点 •能够记录链表的个数(用静态成员) •能返回链表中的节点个数 •能查看链表头节点的元素值 •能告知链表是否为空 •在链表类的构造函数中初始化链表 •在链表类的析构函数中释放链表所有元素的空间 下面给出链表类的类定义,你需要根据该定义完全实现该类。 //用链表实现的列表类 classLinkList{ //定义链表节点类型 typedefstructnode{ intdata; structnode*next; }ListDataNode; //定义链表类型 typedefListDataNode*ListData; protected: intcount;//列表中元素的个数 ListDatadataLinkHead,dataLinkTail;//表头、表尾指针 staticListCount;//列表个数 public: LinkList(void);//构造函数 virtual~LinkList(void);//析构函数 voidputTail(intnewData);//在表尾加入一个新元素 voidputHead(intnewData);//在表头插入一个新元素 intgetHead(void);//从表头取出一个元素 intpeekHead(void);//查看表头元素的值,假定列表至少有一个元素 boolempty();//检查列表是否空 intgetElemCount();//取列表元素个数 staticintgetListNumber();//取列表个数 }; (1)在上面实现的链表类的基础上派生队列类和栈类,要求队列类可以进行元素入队列和出队列操作以及取队列长度操作,栈类可以进行入栈和出栈操作,还可以查看栈顶元素的值。 (2)在队列类中实现一个输出队列内容的函数printQueue,输出格式为: Queuehead-->0: 1: 2: 3 其中,0、1、2、3为队列中的元素,0是队头。 在栈类中实现一个输出栈中内容的函数printStack,输出格式为: Stackmember: |3| |2| |1| |0| ----- 其中,3、2、1、0是栈中元素,3为栈顶元素。 (3)用多文件结构实现程序。 三个类的定义放在一个头文件中,类的实现放在另一个源文件中。 主程序用于测试你所设计的三个类的正确性。 测试内容包括: •在队列中加入几个元素,用printQueue()打印队列内容,然后再从队列中取出这些元素,看是否正确 •在栈中加入几个元素,用printStack()打印栈的内容,然后再从栈中取出这些元素,看是否正确 •测试取队列长度的函数getQueueLength()的正确性 •测试判断栈是否为空的函数empty()的正确性 实验代码: #include usingnamespacestd; structNode { intdata; Node*next; }; classLinkList { public: LinkList(inta[],intn);//构造函数 LinkList(){head=newNode;tail=newNode;head->next=NULL;tail->next=NULL;} ~LinkList();//析构函数 intLength();//求链表长度的函数 intputhead();//在头部插入元素的函数 intputtail();//在尾部插入元素的函数 voidemoty();//检查链表是否为空的函数 intgethead();//从表头取出一个元素 Node*head,*tail; intlength; }; LinkList: : LinkList(inta[],intn) { inti; Node*p,*q; head=newNode; head->data=a[0]; p=newNode; p->data=a[1]; head->next=p; for(i=2;i { q=newNode; q->data=a[i]; p->next=q; p=q; } tail=p; tail->next=NULL; } LinkList: : ~LinkList() { Node*p,*q; p=head; while(p) { q=p; p=p->next; deleteq; } } intLinkList: : Length() { Node*p; inti=0; p=head; while(p) { p=p->next; i++; } returni; } intLinkList: : puthead() { Node*p; p=newNode; cout<<"请输入要插入的元素: "< cin>>p->data; p->next=head; head=p; return0; } intLinkList: : puttail() { Node*p; p=newNode; cout<<"请输入要插入的元素: "< cin>>p->data; tail->next=p; tail=p; tail->next=NULL; return0; } voidLinkList: : emoty() { if(! head->next) cout<<"链表为空"< else cout<<"链表不为空"< } intLinkList: : gethead() { Node*p; p=head; head=head->next; returnp->data; deletep; } classQueue: publicLinkList { public: Queue(inta[],intn): LinkList(a,n){}; voidinqueue();//入队函数 voidoutqueue();//出队函数 }; voidQueue: : inqueue() { LinkList: : puttail(); } voidQueue: : outqueue() { cout<<"Queuehead->"; while(head! =NULL) { cout< : gethead()<<': '; } cout< } classStack: publicLinkList { public:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c+ 派生 继承 实验 报告 材料