多态性和虚函数实验报告.docx
多态性和虚函数 实验报告淮海工学院计算机科学系 实验报告书 课程名: C+程序设计(二) 题 目: 多态性和虚函数 班 级: 学 号: 姓 名: 评语: 成绩: 指导教师: 批阅时间: 年 月 日 C+程序设计实验报告 1、实验内容或题目 声明二维坐标类作为基类派生圆的 类,把派生类圆作为基类,派生圆柱体类。其中,基类二维坐标类有成员数据:x、y坐标值;有成员函数:构造函数实现对基类成员数据的初始化、输出的成员函数,要求输出坐标位置。派生类圆类有新增成员数据:半径;有成员函数:构造函数实现对成员数据的初始化、计算圆面积的成员函数、输出半径的成员函数。派生圆柱体类新增数据有高;新增成员函数有:构造函数、计算圆柱体体积的函数和输出所有成员的函数。请完成程序代码的编写、调试。 教材393页78题。 教材416页1、4、5题。 2、实验目的与要求 理解继承与派生的概念 掌握通过继承派生出一个新的类的方法 了解多态性的概念 了解虚函数的作用与使用方法 3、实验步骤与源程序 实验步骤 先定义一个基类point,及其成员函数,然后以public的继承方式定义子类circle,再定义一个派生类cylinder,最后在main主函数中定义类对象,调用函数实现其功能。 先定义一个基类A及其重载的构造函数,然后以Public派生出子类B,再定义其构造函数,最后在main主函数中定义类对象,调用成员函数实现其功能。 源代码 1.#include <iostream.h> class Point public: Point(float=0,float=0); void setPoint(float,float); float getX const return x; C+程序设计实验报告 float getY const return y; friend ostream & operator<<(ostream &,const Point &); protected: ; Point:Point(float a,float b) x=a;y=b; void Point:setPoint(float a,float b) x=a;y=b; ostream & operator<<(ostream &output,const Point &p) class Circle:public Point public: Circle(float x=0,float y=0,float r=0); void setRadius(float); float getRadius const; float area const; friend ostream &operator<<(ostream &,const Circle &); cout<<""<<p.x<<","<<p.y<<""<<endl; return output; float x,y; protected: ; Circle:Circle(float a,float b,float r):Point(a,b),radius(r) float radius; C+程序设计实验报告 void Circle:setRadius(float r) radius=r; float Circle:getRadius const return radius; float Circle:area const return 3.14159*radius*radius; ostream &operator<<(ostream &output,const Circle &c) cout<<"Center="<<c.x<<","<<c.y<<", area="<<c.area<<endl; class Cylinder:public Circle public: Cylinder (float x=0,float y=0,float r=0,float h=0); void setHeight(float); float getHeight const; float area const; float volume const; friend ostream& operator<<(ostream&,const Cylinder&); return output; r="<<c.radius<<", protected: ; Cylinder:Cylinder(float a,float b,float r,float h):Circle(a,b,r),height(h) float height; C+程序设计实验报告 void Cylinder:setHeight(float h)height=h; float Cylinder:getHeight const return height; float Cylinder:area const return 2*Circle:area+2*3.14159*radius*height; float Cylinder:volume const return Circle:area*height; ostream &operator<<(ostream &output,const Cylinder& cy) cout<<"Center="<<cy.x<<","<<cy.y<<", r="<<cy.radius<<", h="<<cy.height <<"narea="<<cy.area<<", volume="<<cy.volume<<endl; int main Cylinder cy1(3.5,6.4,5.2,10); cout<<"noriginal cylinder:nx="<<cy1.getX<<", y="<<cy1.getY<<", r=" return output; <<cy1.getRadius<<", h="<<cy1.getHeight<<"narea="<<cy1.area <<", volume="<<cy1.volume<<endl; cy1.setHeight(15); cy1.setRadius(7.5); cy1.setPoint(5,5); cout<<"nnew cylinder:n"<<cy1; Point &pRef=cy1; cout<<"npRef as a point:"<<pRef; Circle &cRef=cy1; C+程序设计实验报告 cout<<"ncRef as a Circle:"<<cRef; return 0; 2(1) #include <iostream> using namespace std; class A public: Aa=0;b=0; A(int i)a=i;b=0; A(int i,int j)a=i;b=j; void displaycout<<"a="<<a<<" b="<<b; private: int a; int b; ; class B : public A public: Bc=0; B(int i):A(i)c=0; B(int i,int j):A(i,j)c=0; B(int i,int j,int k):A(i,j)c=k; void display1 display; cout<<" c="<<c<<endl; private: C+程序设计实验报告 int c; ; int main B b1; B b2(1); B b3(1,3); B b4(1,3,5); b1.display1; b2.display1; b3.display1; b4.display1; (2) #include <iostream> using namespace std; class A public: Acout<<"constructing A "<<endl; return 0; Acout<<"destructing A "<<endl; ; class B : public A public: Bcout<<"constructing B "<<endl; Bcout<<"destructing B "<<endl; ; C+程序设计实验报告 class C : public B public: Ccout<<"constructing C "<<endl; Ccout<<"destructing C "<<endl; ; int main C c1; return 0; 3.(1)/Point.h class Point public: Point(float=0,float=0); void setPoint(float,float); float getX const return x; float getY const return y; friend ostream & operator<<(ostream &,const Point &); protected: /Point.cpp Point:Point(float a,float b) x=a;y=b; void Point:setPoint(float a,float b) x=a;y=b; ostream & operator<<(ostream &output,const Point &p) float x,y; C+程序设计实验报告 output<<""<<p.x<<","<<p.y<<""<<endl; return output; /Circle.h #include "point.h" class Circle:public Point public: Circle(float x=0,float y=0,float r=0); void setRadius(float); float getRadius const; float area const; friend ostream &operator<<(ostream &,const Circle &); protected: float radius; ; /Circle.cpp Circle:Circle(float a,float b,float r):Point(a,b),radius(r) void Circle:setRadius(float r) radius=r; float Circle:getRadius const return radius; float Circle:area const return 3.14159*radius*radius; ostream &operator<<(ostream &output,const Circle &c) output<<"Center="<<c.x<<","<<c.y<<", area="<<c.area<<endl; return output; r="<<c.radius<<", C+程序设计实验报告 /Cylinder.h #include "circle.h" class Cylinder:public Circle public: Cylinder (float x=0,float y=0,float r=0,float h=0); void setHeight(float); float getHeight const; float area const; float volume const; friend ostream& operator<<(ostream&,const Cylinder&); protected: float height; ; /Cylinder.cpp Cylinder:Cylinder(float a,float b,float r,float h) :Circle(a,b,r),height(h) void Cylinder:setHeight(float h)height=h; float Cylinder:getHeight const return height; float Cylinder:area const return 2*Circle:area+2*3.14159*radius*height; float Cylinder:volume const return Circle:area*height; ostream &operator<<(ostream &output,const Cylinder& cy) output<<"Center="<<cy.x<<","<<cy.y<<", r="<<cy.radius<<", h="<<cy.height C+程序设计实验报告 <<"narea="<<cy.area<<", volume="<<cy.volume<<endl; return output; /main.cpp #include <iostream.h> #include "cylinder.h" #include "point.cpp" #include "circle.cpp" #include "cylinder.cpp" int main Cylinder cy1(3.5,6.4,5.2,10); cout<<"noriginal cylinder:nx="<<cy1.getX<<", y="<<cy1.getY<<", r=" <<cy1.getRadius<<", h="<<cy1.getHeight<<"narea="<<cy1.area <<", volume="<<cy1.volume<<endl; cy1.setHeight(15); cy1.setRadius(7.5); cy1.setPoint(5,5); cout<<"nnew cylinder:n"<<cy1; Point &pRef=cy1; cout<<"npRef as a point:"<<pRef; Circle &cRef=cy1; cout<<"ncRef as a Circle:"<<cRef; return 0; (2) #include <iostream> using namespace std; class Shape public: virtual double area const =0; C+程序设计实验报告 ; class Circle:public Shape public: Circle(double r):radius(r) virtual double area const return 3.14159*radius*radius; protected: ; class Rectangle:public Shape public: Rectangle(double w,double h):width(w),height(h) virtual double area const return width*height; double radius; protected: ; class Triangle:public Shape public: Triangle(double w,double h):width(w),height(h) virtual double area const return 0.5*width*height; double width,height; protected: ; void printArea(const Shape &s) double width,height; C+程序设计实验报告 cout<<s.area<<endl; int main (3) #include <iostream> using namespace std; class Shape public: ; class Circle:public Shape public: Circle(double r):radius(r) virtual double area const return 3.14159*radius*radius; virtual double area const =0; Circle circle(12.6); cout<<"area of circle =" printArea(circle); Rectangle rectangle(4.5,8.4); cout<<"area of rectangle =" printArea(rectangle); Triangle triangle(4.5,8.4); cout<<"area of triangle =" printArea(triangle); return 0; protected: double radius; C+程序设计实验报告 ; class Square:public Shape public: Square(double s):side(s) virtual double area const return side*side; protected: ; class Rectangle:public Shape public: Rectangle(double w,double h):width(w),height(h) virtual double area const return width*height; double side; protected: ; class Trapezoid:public Shape public: Trapezoid(double t,double b,double h):top(t),bottom(t),height(h) virtual double area const return 0.5*(top+bottom)*height; double width,height; protected: ; class Triangle:public Shape double top,bottom,height; C+程序设计实验报告 public: Triangle(double w,double h):width(w),height(h) virtual double area const return 0.5*width*height; protected: ; int main Circle circle(12.6); double width,height; Square square(3.5); Rectangle rectangle(4.5,8.4); Trapezoid trapezoid(2.0,4.5,3.2); Triangle triangle(4.5,8.4); Shape *pt5=&circle,&square,&rectangle,&trapezoid,▵ double areas=0.0; for(int i=0;i<5;i+) areas=areas+pti->area; cout<<"totol of all areas="<<areas<<endl; return 0; 4、测试数据与实验结果 C+程序设计实验报告 C+程序设计实验报告 5、结果分析与实验体会 继承时,子类对基类的访问属性,基类的私有成员无论以何种方式继承在子类中都是不可访问的,唯有调用基类中的成员函数方可访问其私有变量。另外,派生类构造函数的总参数列表中的参数,应当包括基类构造函数和子对象的参数列表中的参数。而多层派生时,只需写出其直接基类的构造函数即可。 如果在基类中定义了没有参数的构造函数,那么在定义派生类构造函数时可以不写基类构造函数,在调用派生类构造函数时,系统会自动首先调用基类的默认构造函数;如果在基类或子对象类型的声明中定义了参数的构造函数,那么就必须显式地定义派生类构造函数,并在派生类构造函数中写出基类或子对象类型的构造函数及其参数表。