多态性和虚函数 实验报告
实验6 多态性(一)
福建农林大学实验报告实验6 多态性(一)一、实验目的和要求(1)掌握虚函数的定义与使用方法,进一步理解多态性的概念和分类。
(2)了解纯虚函数和抽象类的使用方法。
二、实验内容和原理1、分析并调试下列程序,回答以下问题:(1)指出抽象类(2)指出虚函数,并说明它的作用(3)每个类的作用是什么?整个程序的作用是什么?2、使用虚函数编写程序求球体、圆柱体和圆锥的体积,由于球体、圆柱体和圆锥都可以看做由圆继承而来,所以可以定义圆类作为基类。
在圆类中定义数据成员半径和一个求体积的虚函数。
由圆类派生出球体类、圆柱体类和圆锥类,在派生类中对圆类中的虚函数重新定义。
编写一个外部函数求各类形状的总体积。
最后在main()函数中构造若干形状,并求它们的体积和。
三、实验环境1. 硬件:PC机;2. 软件:Windows操作系统、Visual C++ 6.0四、算法描述及实验步骤1、算法描述及步骤如下:(1)根据题目要求编写好程序代码并在VC环境下输入源程序。
(2)检查程序有无错误(包括语法错误和逻辑错误),有则改之。
(3)编译和连接,仔细分析编译信息,如有错误应找出原因并改正之。
本题改正后的代码如下:#include<iostream.h>const double PI=3.1415;class Shap{public:virtual double Area()=0;};class Triangle:public Shap{public:Triangle(double h,double w){H=h;W=w;}double Area(){return 0.5*H*W;}private:double H,W;};class Circle:public Shap{public:Circle(double r){R=r;}double Area(){return PI*R*R;}private:double R;};double Total(Shap*s[],int n){double sum=0;for(int i=0;i<n;i++)sum+=s[i]->Area();}return sum;}int main(){Shap*s[2];s[0]=new Triangle(5.0,4.0);s[1]=new Circle(8.0);double sum=Total(s,2);cout<<"sum="<<sum<<endl;return 0;}(4)运行程序,输入数据,分析结果。
虚函数与多态性实验
一.实验目的及要求1.进一步熟悉类的设计、运用继承与派生机制设计派生类,合理设置数据成员和成员函数。
2.掌握通过继承、虚函数、基类的指针或引用实现动态多态性的方法。
3.理解并掌握具有纯虚函数的抽象类的作用,在各派生类中重新定义各纯虚函数的方法,以及此时实现的动态多态性。
二.实验内容在自己的文件夹下建立一个名为exp5的工程,在该工程中做如下操作:定义一个抽象类容器类,其中定义了若干纯虚函数,实现求表面积、体积、输出等功能。
由此抽象类派生出正方体、球体和圆柱体等多个派生类,根据需要定义自己的成员变量,在各个派生类中重新定义各纯虚函数,实现各自类中相应功能,各个类成员的初始化均由本类构造函数实现。
(1)在主函数中,定义容器类的指针和各个派生类的对象,使指针指向不同对象处调用相同的函数能执行不同的函数代码,从而实现动态多态性。
(2)定义一个顶层函数void TopPrint(Container &r);使得主函数中调用该函数时,根据实在参数所有的类自动调用对应类的输出函数。
(3)主函数中定义一个Container类对象,观察编译时的错误信息,从而得出什么结论三.实验程序及运行结果#include <iostream>using namespace std;class Base{public:virtual void f(){ cout << "调用Base::f()" << endl; }};class Derived: public Base{public:void f(){ cout << "调用Derived::f()" << endl; } // 虚函数};int main(void){Derived obj; // 定义派生类对象Base *p = &obj; // 基类指针p->f(); // 调用函数f()system("PAUSE");return 0;}2.#include <iostream>using namespace std; //class Base{public:virtual void Show() const{ cout << "调用Base::Show()" << endl; } // 虚函数};class Derived: public Base{public:void Show() const{ cout << "调用Derived::Show()" << endl; }};void Refers(const Base &obj) // 基类引用{obj.Show(); // 调用函数Show()}int main(void){Base obj1;Derived obj2; // 定义对象Refers(obj1); // 调用函数Refers()Refers(obj2);system("PAUSE");return 0;}3.#include <iostream>using namespace std; /class Base{private:int m;public:Base(int a): m(a){ }virtual void Show() const{ cout << m << endl; }// 虚函数};class Derived: public Base{private:int n;public:Derived(int a, int b): Base(a), n(a){ } // 构造函数void Show() const{cout << n << ","; /Base::Show(); // 调用基类的Show() }};int main(void){Base obj1(168);Derived obj2(158, 98);Base *p;p = &obj1;p->Show();p = &obj2;p->Show();p->Base::Show();system("PAUSE");return 0;}4.#include <iostream>using namespace std;class A{public:virtual void Show() const{ cout << "基类A" << endl; } };class B: public A{public:void Show() const{ cout << "派生类B" << endl; } };int main(void){B obj;A *p = &obj;p->Show();system("PAUSE");return 0;}5.#include <iostream>using namespace std;const double PI = 3.1415926;class Shape{public:virtual void Show() const = 0;static double sum;};class Circle: public Shape{private:double radius;public:Circle(double r): radius(r){ sum += PI * radius * radius; }void Show() const{cout << "圆形:" << endl;cout << "半径:" << radius << endl;cout << "面积:" << PI * radius * radius << endl;}};class Rectangle: public Shape{private:double height;double width;public:Rectangle(double h, double w): height(h), width(w){ sum += height * width; }void Show() const{cout << "矩形:" << endl;cout << "高:" << height << endl;cout << "宽:" << width << endl;cout << "面积:" << height * width << endl;}};double Shape::sum = 0;int main(void){char flag = 'Y'; 'Shape *p;while (toupper(flag) == 'Y'){cout << "请选择输入类别(1.圆形2.矩形)";int select;cin >> select;switch (select){case 1:double r;cout << "输入半径:";cin >> r;p = new Circle(r);p->Show();delete p;break;case 2:double h, w;cout << "输入高:";cin >> h;cout << "输入宽:";cin >> w;p = new Rectangle(h, w);p->Show(); // 显示相关信息delete p; // 释放存储空间break;default: // 其它情况, 表示选择有误cout << "选择有误!"<< endl;break;}cout << endl << "是否继续录入信息?(Y/N)";cin >> flag;}cout << "总面积:" << Shape::sum << endl;system("PAUSE");return 0;}6.#include <iostream>using namespace std;const double PI = 3.1415926;const int NUM = 10;class Shape{public:virtual void ShowArea() const = 0;static double sum;};class Circle: public Shape{private:double radius;public:Circle(double r): radius(r){ sum += PI * radius * radius; }void ShowArea() const{ cout << "圆面积:" << PI * radius * radius << endl; }};class Rectangle: public Shape{private:double height;double width;public:Rectangle(double h, double w): height(h), width(w){ sum += height * width; }void ShowArea() const{ cout << "矩形面积:" << height * width << endl; }};class Square: public Shape{private:double length;public:Square(double a): length(a){ sum += length * length; }void ShowArea() const{ cout << "正方形面积:" <<length * length << endl; } };double Shape::sum = 0;int main(void){Shape *shape[NUM];int count = 0;while (count < NUM){cout << "请选择(1.圆形2.矩形3.正方形4.退出):";int select;cin >> select;if (select == 4) break;switch (select){case 1:double r;cout << "输入半径:";cin >> r;shape[count] = new Circle(r);shape[count]->ShowArea();count++;break;case 2:double h, w;cout << "输入高:";cin >> h;cout << "输入宽:";cin >> w;shape[count] = new Rectangle(h, w);shape[count]->ShowArea();count++;break;case 3:double a;cout << "输入边长:";cin >> a;shape[count] = new Square(a);shape[count]->ShowArea();count++;break;default:cout << "选择有误!"<< endl;break;}}cout << "总面积:" << Shape::sum << endl;for (int i = 0; i < count; i++) delete shape[i];system("PAUSE");return 0;}五.实验总结通过本次试验 我更深刻的理解了某些语句如何使用及结构体的优点 也能更加熟练的编写简单的程序了 我深知实践要比书本更加重要 今后还要多练习 在实践中学习。
实验9 多态与虚函数
Point(){}
~Point(){cout<<"executing Point destructor"<<endl;}
};
class Circle:public Point
{public:
Circle(){}
~Circle(){cout<<"executing Ciecle destructor"<<endl;}
private:
int radus;
};
int main()
{Point*p=new Circle;
delete p;
return 0;
}
答:(1)构造函数中能调用虚函数采用动态联编
(2)当基类的析构函数为虚函数时,无论指针指的是哪一类族中的哪一个类对象,系统都会采用动态关联,调用相应类的析构函数。
3、理解静态关联编和动态关编的概念,加深对如何实现动态联编的了解。
4、掌握纯虚函数和抽象类的概念;
5、通过上机练习进一步体会抽象类的作用,以及如何使用抽象类。
二、实验设备(环境)及要求
硬件:PC(P 以上,128M以上内存)、因特网接入;
软件:Windows XP操作系统或更高版本、Office2003或更高版本、Visual C++6.0。
class Shape
{public:
virtual double area() const =0; //纯虚函数
};
//定义Circle(圆形)类
class Circle:public Shape
{public:
Circle(double r):radius(r){} //结构函数
c++多态性实验报告
实验3 多态性实验课程名:面向对象程序设计(C++)专业班级:学号:姓名:实验时间:实验地点:指导教师:3.1实验目的和要求(1) 了解多态性的概念。
(2) 掌握运算符重载的基本方法。
(3) 掌握虚函数的定义和使用方法。
(4) 掌握纯虚函数和抽象类的概念和用法。
二、实验内容一、构建一个复数类Complex,试对下列几个运算符进行重载:++,=,!=,+,-,==,其中要求要有成员重载形式和友元重载形式,而且,++运算符要求实现先加和后加两种形式。
该类定义原型说明:class complex{public:complex(double r=0,double i=0);complex &operator +(complex &c);complex operator -(complex &c);complex operator *(complex &c);friend complex operator /(complex &c1,complex &c2);friend int operator ==(complex &c1,complex &c2);friend int operator !=(complex &c1,complex &c2);//friend complex operator++(complex &c);complex operator++();complex operator++(int);void disp();private:double real;double imag;};实验代码如下:#include<iostream>using namespace std;class complex{public:complex(){real=0;imag=0;}complex(double r,double i){real=r;imag=i;}complex operator +(complex &c);complex operator -(complex &c);complex operator *(complex &c);friend complex operator /(complex &c1,complex &c2);friend int operator ==(complex &c1,complex &c2);friend int operator !=(complex &c1,complex &c2);//friend complex operator++(complex &c);complex operator++();complex operator++(int);void display();double real;double imag;};complex complex::operator +(complex &c){complex c1;c1.real=real+c.real;c1.imag=imag+c.imag;return c1;}complex complex::operator -(complex &c){complex c1;c1.real=real-c.real;c1.imag=imag-c.imag;return c1;}complex complex::operator *(complex &c){complex c1;c1.real=real*c.real-imag*c.imag;c1.imag=real*c.imag+imag*c.real;return c1;}complex operator /(complex &c1,complex &c2){complex c;c.real=(c1.real*c2.real+c1.imag*c2.imag)/(c2.imag* c2.imag+c2.real*c2.real);c.imag=(c1.real*c2.imag-c1.imag*c2.real)/(c2.imag* c2.imag+c2.real*c2.real);return c;}int operator ==(complex &c1,complex &c2) {if(c1.real==c2.real&&c1.imag==c2.imag) {return 1;}}int operator !=(complex &c1,complex &c2) {if(c1.real!=c2.real||c1.imag!=c2.imag) return 1;}complex complex::operator++(){return complex(real+1,imag);}complex complex::operator ++(int){return complex(real,imag);real=real+1;}void complex::display(){cout<<'('<<real<<','<<imag<<'i'<<')'<<endl; }int main(){complex c1(1,2),c2(2.1,4.5),c3;c3=c1+c2;cout<<"c1+c2=";c3.display();c3=c1-c2;cout<<"c1-c2";c3.display();c3=c1*c2;cout<<"c1*c2=";c3.display();c3=c1/c2;cout<<"c1/c2";c3.display();c3=c1++;cout<<"c1++=";c3.display();c3=++c1;cout<<"++c1=";c3.display();return 0;}运行结果:代码分析:1)在复数类中定义了四则运算的重载函数以及比较大小的函数,当满足比较符的大小关系时返回1否则返回0;2)当重载函数为类函数时只需一个参数,为友元函数时需要两个参数;3)对于‘++’与‘--’,如果在自增(自减)函数中,增加一个int型的参数,就是后置自增运算符函数二、建立一个分数类Fraction。
实验6 多态性与虚函数
实验6 多态性与虚函数一.实验目的1.了解多态的概念;2.了解静态联编和动态联编的概念;3.掌握动态联编的条件;4.了解虚函数的用途及使用方法。
二源程序#include<iostream>using namespace std;class Shape{public:virtual double area()const=0;virtual void display()=0;};class TwoDimShape:public Shape{};class ThreeDimShape:public Shape{};class Circle:public TwoDimShape{public:Circle(double r){R=r;}double area()const{return 3.14*3.14*R;}void display(){cout<<"圆的面积为:"<<area()<<endl;}private:double R;};class Cube:public ThreeDimShape{public:Cube(double l){L=l;}double area()const{return 6*L*L;}void display(){cout<<"立方体的表面积为:"<<area()<<endl;} private:double L;};int main(){int i;Circle Ci1(5.2);Cube Cu1(3.3);Shape *S1[2]={&Ci1,&Cu1};for(i=0;i<2;i++){S1[i]->area();S1[i]->display();}return 0;}三.编程思想圆和立方体不属于同一类,这两类的参数不同计算方法不同,但是所求的都是面积输出的也都是面积这一个相同的成员函数。
实验四 虚函数与多态性
实验四虚函数与多态性实验目的和要求 :1 了解多态性在 C++ 中的体现。
2 掌握虚函数的应用。
3 了解抽象类。
实验内容:定义一个基类为哺乳动物类Mammal,其中有数据成员年龄、重量、品种,有成员函数move()、speak()等,以此表示动物的行为。
由这个基类派生出狗、猫、马、猪等哺乳动物,它们有各自的行为。
编程分别使各个动物表现出不同的行为。
要求如下:1、从基类分别派生出各种动物类,通过虚函数实现不同动物表现出的不同行为。
2、今有狗: CAIRN:3岁,3kg;DORE:4岁,2kg;猫: CAT:5 岁,4kg;马: HORSE,5岁,60kg;猪: PIG,2岁,45kg。
3、设置一个 Mammal 类数组,设计一个屏幕菜单,选择不同的动物或不同的品种,则显示出动物相对应的动作,直到选择结束。
4、对应的动作中要先显示出动物的名称,然后显示年龄、重量、品种、叫声及其他特征。
实验原理:1.多态性:多态是指同样的消息被不同类型的对象接受时导致不同的行为,所谓消息是指对类的成员函数的调用,而不同的行为是指不同的实现,也就是调用不同的函数。
多态性从实现的角度来讲可以划分为两类:编译时的多态性和运行时的多态性。
编译时的多态性是在编译的过程中确定同名操作的具体操作对象,也就是通过重载函数来实现的。
运行时的的多态性是在程序运行过程中才动态地确定操作所针对的具体对象,使用虚函数来实现的。
2.虚函数:虚函数是重载的另一种形式,它提供了一种更为灵活的多态性机制。
虚函数允许函数调用与函数体之间的联系在运行时才建立,也就是运行时才决定如何动作,即所谓的“动态连接”。
虚函数成员的定义:virtual 函数类型函数名(形参表)3.(1)抽象类:抽象类是一种特殊的类。
抽象类是为了抽象和设计的目的而建立的。
一个抽象类自身无法实例化,也就是说无法定义一个抽象类的对象,只能通过继承机制,生成抽象类的非抽象派生类,然后再实例化。
多态性与虚函数实验报告
cout<<"三角形的底为:"<<width<<"高为:"<<height <<"面积为:"<<width*height/2<<endl;
}
private:
float width,height;
};
class Circle:public Base
{
public:
Circle(float r){radius = r;}
p= &obj1;
p->area();
p=&obj2;
p->area();
return 0;
}
【实验结果与数据处理】
【实验结论】
分析:用虚函数实现多态。
【实验器材】
微型计算机、Visual C++ 6.0集成软件平台
【实验步骤】
1.编辑源程序。
2.对源程序进行编译并调试程序。
3.连接并运行程序。
4.检查输出结果是否正确。程序设计如下:
#include<iostream.h>
const float PI = 3.14;
class Base
多态性与虚函数实验报告
实验题目
多态性与虚函数
日期
班级
组别
姓名
类型
【实验目的】
1.理解多态性的概念。
2.了解编译时的多态和运行时的多态。
3.掌握虚函数的定义及实现,掌握虚析构函数的使用方法。
4.了解纯虚函数和抽象类的关系及用法。
【实验原理】
设计一个基类Base,其作用是计算一个图形的面积,它只有一个公有的函数成员虚函数area。再从Base类公有派生一个三角形类Triangle和一个圆类Circle,在类Triangle和类Circle中分别定义自己的area函数,用于计算各自的面积。在主函数中设计一个Base类的对象指针,分别指向类Triangle和类Circle的对象,调用各自的area函数显示相应对象的面积。
多态性与虚函数实验报告
多态性与虚函数实验报告实验目的:通过实验掌握多态性和虚函数的概念及使用方法,理解多态性实现原理和虚函数的应用场景。
实验原理:1.多态性:多态性是指在面向对象编程中,同一种行为或者方法可以具有多种不同形态的能力。
它是面向对象编程的核心特性之一,能够提供更加灵活和可扩展的代码结构。
多态性主要通过继承和接口来实现。
继承是指子类可以重写父类的方法,实现自己的特定行为;接口是一种约束,定义了类应该实现的方法和属性。
2.虚函数:虚函数是在基类中声明的函数,它可以在派生类中被重新定义,以实现多态性。
在类的成员函数前面加上virtual关键字,就可以将它定义为虚函数。
当使用基类指针或引用调用虚函数时,实际调用的是派生类的重写函数。
实验步骤:1. 创建一个基类Shape,包含两个成员变量color和area,并声明一个虚函数printArea(用于打印面积。
2. 创建三个派生类Circle、Rectangle和Triangle,分别继承Shape类,并重写printArea(函数。
3. 在主函数中,通过基类指针分别指向派生类的对象,并调用printArea(函数,观察多态性的效果。
实验结果与分析:在实验中,通过创建Shape类和派生类Circle、Rectangle和Triangle,可以实现对不同形状图形面积的计算和打印。
当使用基类指针调用printArea(函数时,实际调用的是派生类的重写函数,而不是基类的函数。
这就是多态性的实现,通过基类指针或引用,能够调用不同对象的同名函数,实现了对不同对象的统一操作。
通过实验1.提高代码的可扩展性和灵活性:通过多态性,可以将一类具有相似功能的对象统一管理,节省了代码的重复编写和修改成本,增强了代码的可扩展性和灵活性。
2.简化代码结构:通过虚函数,可以将各个派生类的不同行为统一命名为同一个函数,简化了代码结构,提高了代码的可读性和维护性。
3.支持动态绑定:通过运行时的动态绑定,可以根据对象的实际类型来确定调用的函数,实现了动态绑定和多态性。
实验九 多态性与虚函数
实验九多态性与虚函数一、实验要求1.领悟面向对象编程技术的多态性特征。
2.熟练掌握虚函数的设计和使用。
二、实验内容1.定义一个类A,有两个add成员函数,参数是数字类型,就为加法;参数是字符类型,就为字符转化为字符串,并实现连接,请用程序实现。
2. 有一个汽车类vehicle,将它作为基类派生类小车类car、卡车类truck和轮船类boat,定义这些类并定义一个虚函数用来显示各类信息。
三、实验小结#include <iostream>using namespace std;class vehicle{public:virtual void pr(){cout<<"this is a vehicle"<<endl;}};class Car:public vehicle{public:void pr(){cout<<"this is a car"<<endl;}};class truck:public vehicle{public:void pr(){cout<<"this is a truck"<<endl;} };class boat:public vehicle{public:void pr(){cout<<"this is a boat"<<endl;} };void main(){vehicle *p1 = new Car;p1->pr();vehicle *p2 = new truck;p2->pr();vehicle *p3 = new boat;p3->pr();vehicle *p4 = new vehicle;p4->pr();delete p1;delete p2;delete p3;delete p4;}#include<iostream>using namespace std;class Vehicle{public:virtual void pr()=0; protected:char Name[20];};class Car:public Vehicle{public:Car(char *name){strcpy(Name,name);}void pr(){cout<<Name<<endl;}};class Truck:public Vehicle{public:Truck(char *name){ strcpy(Name,name); }void pr(){cout<<Name<<endl;}};class Boat:public Vehicle{public:Boat(char *name){ strcpy(Name,name); }void pr(){cout<<Name<<endl;}};void main(){Vehicle *vp;Car car("奔驰");Truck truck("运输卡车");Boat boat("游艇");vp=&car;vp->pr ();vp=&truck;vp->pr ();vp=&boat;vp->pr ();}。
多态性和虚函数 实验报告
淮海工学院计算机科学系实验报告书课程名:《 C++程序设计(二)》题目:多态性和虚函数班级:学号:姓名:1、实验内容或题目(1)声明二维坐标类作为基类派生圆的类,把派生类圆作为基类,派生圆柱体类。
其中,基类二维坐标类有成员数据:x、y坐标值;有成员函数:构造函数实现对基类成员数据的初始化、输出的成员函数,要求输出坐标位置。
派生类圆类有新增成员数据:半径(R);有成员函数:构造函数实现对成员数据的初始化、计算圆面积的成员函数、输出半径的成员函数。
派生圆柱体类新增数据有高(H);新增成员函数有:构造函数、计算圆柱体体积的函数和输出所有成员的函数。
请完成程序代码的编写、调试。
(2)教材393页7-8题。
(3)教材416页1、4、5题。
2、实验目的与要求(1)理解继承与派生的概念(2)掌握通过继承派生出一个新的类的方法(3)了解多态性的概念(4)了解虚函数的作用与使用方法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;}float getY() const {return y;}friend ostream & operator<<(ostream &,const Point &); protected:float x,y;};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){cout<<"["<<p.x<<","<<p.y<<"]"<<endl;return output;}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::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){cout<<"Center=["<<c.x<<","<<c.y<<"], r="<<c.radius<<", area="<<c.area()<<endl;return output;}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::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){cout<<"Center=["<<cy.x<<","<<cy.y<<"], r="<<cy.radius<<", h="<<cy.height <<"\narea="<<cy.area()<<", volume="<<cy.volume()<<endl;return output;}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.(1)#include <iostream>using namespace std;class A{public:A(){a=0;b=0;}A(int i){a=i;b=0;}A(int i,int j){a=i;b=j;}void display(){cout<<"a="<<a<<" b="<<b;} private:int a;int b;};class B : public A{public:B(){c=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: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();return 0;}(2)#include <iostream>using namespace std;class A{public:A(){cout<<"constructing A "<<endl;} ~A(){cout<<"destructing A "<<endl;} };class B : public A{public:B(){cout<<"constructing B "<<endl;} ~B(){cout<<"destructing B "<<endl;} };class C : public B{public:C(){cout<<"constructing C "<<endl;}~C(){cout<<"destructing C "<<endl;}};int main(){C c1;return 0;}3.(1)//Point.hclass 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:float x,y;}//Point.cppPoint::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){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.cppCircle::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<<"], r="<<c.radius<<", area="<<c.area()<<endl;return output;}//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.cppCylinder::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<<"\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;class Circle:public Shape{public:Circle(double r):radius(r){} virtual double area() const {return 3.14159*radius*radius;}; protected:double radius;};class Rectangle:public Shape{public:Rectangle(double w,double h):width(w),height(h){} virtual double area() const {return width*height;} protected:double width,height; };class Triangle:public Shape{public:Triangle(double w,double h):width(w),height(h){} virtual double area() const {return 0.5*width*height;} protected:double width,height; };void printArea(const Shape &s)cout<<s.area()<<endl;} int main(){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;}(3)#include <iostream>using namespace std;class Shape{public:virtual double area() const =0;};class Circle:public Shape{public:Circle(double r):radius(r){}virtual double area() const {return 3.14159*radius*radius;}; protected:double radius;class Square:public Shape{public:Square(double s):side(s){}virtual double area() const {return side*side;}protected:double side;};class Rectangle:public Shape{public:Rectangle(double w,double h):width(w),height(h){}virtual double area() const {return width*height;}protected:double width,height; };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;} protected:double top,bottom,height;};class Triangle:public Shapepublic:Triangle(double w,double h):width(w),height(h){}virtual double area() const {return 0.5*width*height;} protected:double width,height;};int main(){Circle circle(12.6);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 *pt[5]={&circle,&square,&rectangle,&trapezoid,&triangle};double areas=0.0;for(int i=0;i<5;i++){areas=areas+pt[i]->area();}cout<<"totol of all areas="<<areas<<endl;return 0;}4、测试数据与实验结果(可以抓图粘贴)5、结果分析与实验体会继承时,子类对基类的访问属性,基类的私有成员无论以何种方式继承在子类中都是不可访问的,唯有调用基类中的成员函数方可访问其私有变量。
实验8 多态--虚函数
实验八多态—虚函数实验目的:1.学习为什么要使用虚函数。
2.学习如何声明函数为虚函数。
3.学习如何声明异类数组(类型为基类指针,指针分别指向不同的子类对象)。
4.学习如何使用虚函数和异类数组实现多态调用。
实验内容(与实验六相同):创建一个银行账户的继承层次,表示银行的所有客户账户。
所有的客户都能在他们的银行账户存钱,取钱,但是账户也可以分成更具体的类型。
例如,一方面存款账户SavingsAccount依靠存款生利,另一方面支票账户CheckingAccount 对每笔交易(即存款或取款)收取费用。
创建一个类层次,以Account作为基类,SavingsAccount和CheckingAccount 作为派生类。
基类Account应该包括一个double类型的数据成员balance,表示账户的余额。
该类应当提供三个成员函数。
成员函数credit可以向当前余额加钱;成员函数debit负责从账户中取钱,并且保证账户不会被透支。
如果提取金额大于账户金额,函数将保持balance不变,并打印信息“Debit amount exceeded account balance”;成员函数getBalance则返回当前balance的值。
派生类SavingsAccount不仅继承了基类Account的功能,而且还应提供一个附加的double类型数据成员interestrate表示这个账户的比率(百分比)。
SavingsAccount的构造函数应接受初始余额值和初始利率值,还应提供一个public成员函数calculateInterest,返回代表账户的利息的一个double值,这个值是balance和interestrate的乘积。
注意:类SavingsAccount应继承成员函数credit 和debit,不需要重新定义。
派生类CheckingAccount不仅继承了基类Account的功能,还应提供一个附加的double类型数据成员表示每笔交易的费用。
实验报告7虚函数与多态性
实验七虚函数与多态性班级: 11511 学号: 20113051131 姓名:张文静成绩:1、实验目的(1)掌握动态联编的概念;(2)掌握虚函数和纯虚函数的使用方法;(3)掌握抽象类的使用。
2、实验内容编写满足以下条件的程序。
(1)定义一个类Basefly,该类中有一个Fly()函数。
定义3个类Birdfly、Dragonfly和Planefly,都继承自Basefly类,并重载Fly()函数。
用各类的指针调用各个类的对象的Fly()函数,体会继承中的多态性。
将Basefly::Fly()函数声明为虚函数,体会虚函数在多态性中的应用。
(2)定义一个表示学生的类XS,包括成员函数XM()、XB()和NL(),分别用来显示学生的姓名、性别和年龄,并将它们全部定义为虚函数;定义一个类CZS表示初中生,包含数据成员xm、xb和nl,分别表示初中生的姓名、性别和年龄,包括成员函数XM()、XB()和NL(),分别用来显示初中生的姓名、性别和年龄;再定义一个类GZS表示高中生和一个类DXS表示大学生,同样包含数据成员xm、xb和nl,也包括成员函数XM()、XB()和NL()。
①设计基类XS及其派生类CZS、GZS和DXS。
②分别生成CZS、GZS和DXS类的对象。
③将CZS、GZS和DXS类对象的指针赋给XS类的指针变量。
④分别用XS类的指针和引用访问成员函数XM()、XB()和NL()。
⑤分析程序运行结果。
3、实验结果编写相应程序,并调试运行。
(1)#include<iostream>using namespace std;class Basefly{public:virtual void Fly()=0;};class Birdfly:public Basefly{public:void Fly(){cout<<"Birdfly中Fly()函数被调用!"<<endl;} };class Dragonfly:public Basefly{public:void Fly(){cout<<"Dragonfly中Fly()函数被调用!"<<endl;} };class Planefly:public Basefly{public:void Fly(){cout<<"Planefly中Fly()函数被调用!"<<endl;} };void main(){Basefly *p;Birdfly b1;Dragonfly d1;Planefly p1;p=&b1;p->Fly();p=&d1;p->Fly();p=&p1;p->Fly();}运行结果:#include<iostream>#include<string>using namespace std;class XS{public:XS(string n,string s,int a){ xm=n; xb=s; nl=a; }virtual void XM()=0;virtual void XB()=0;virtual void NL()=0;protected:string xm,xb;int nl;};class CZS:public XS{public:CZS(string n,string s,int a):XS(n,s,a){}void XM(){cout<<"初中生的姓名是:"<<xm<<endl;} void XB(){cout<<"初中生的性别是:"<<xb<<endl;} void NL(){cout<<"初中生的年龄是:"<<nl<<endl;} };class GZS:public XS{public:GZS(string n,string s,int a):XS(n,s,a){}void XM(){cout<<"高中生的姓名是:"<<xm<<endl;}void XB(){cout<<"高中生的性别是:"<<xb<<endl;}void NL(){cout<<"高中生的年龄是:"<<nl<<endl;} };class DXS:public XS{public:DXS(string n,string s,int a):XS(n,s,a){}void XM(){cout<<"大学生的姓名是:"<<xm<<endl;}void XB(){cout<<"大学生的性别是:"<<xb<<endl;}void NL(){cout<<"大学生的年龄是:"<<nl<<endl;} };void main(){XS *p;CZS c1("张三","男",14);GZS g1("李四","男",17);DXS d1("王丽","女",20);p=&c1; p->XM();p=&c1; p->XB();p=&c1; p->NL();p=&g1; p->XM();p=&g1; p->XB();p=&g1; p->NL();p=&d1; p->XM();p=&d1; p->XB();p=&d1; p->NL();}运行结果:总结:。
下载-第五章多态性和虚函数解读
下载-第五章多态性和虚函数解读实验四多态性与虚函数⼀、实验⽬的和要求1 了解多态性在C++中的体现;2 掌握虚函数的应⽤;3 了解抽象类。
⼆、基本概念多态性多态是指同样的消息被不同类型的对象接收时导致不同的⾏为,所谓消息是指对类的成员函数调⽤,不同的⾏为是指不同的实现,也就是调⽤了不同的函数。
多态性可以分为四类:重载多态、强制多态、包含多态和参数多态。
多态从实现的⾓度来讲可以划分为两类:编译时的多态和运⾏时的多态。
编译时的多态性是在编译的过程中确定了同名操作的具体操作对象,也就是通过重载函数来实现的。
运⾏时的多态性是在程序运⾏过程中才动态地确定操作所针对的具体对象,就是⽤虚函数来实现的。
虚函数虚函数是重载的另⼀种表现形式,它是⼀种动态的重载⽅式,它提供了⼀种更为灵活的多态性机制。
虚函数允许函数调⽤与函数体之间的联系在运⾏时才建⽴,也就是在运⾏时才决定如何动作,即所谓的“动态连接”。
⼀般虚函数成员的定义语法是:virtual 函数类型函数名(形参表)虚函数的定义实际就是在原有的普通函数成员前⾯使⽤virtual关键字来限定,虚函数声明只能出现在类定义中的函数原型声明中,⽽不能在成员的函数体中。
运⾏过程中的多态需要满⾜三个条件,⾸先类之间应满⾜赋值兼容规则,其⼆是要声明虚函数,第三是要由成员函数来调⽤或者是通过指针、引⽤来访问虚函数。
抽象类抽象类是⼀种特殊的类,它为⼀族类提供统⼀的操作界⾯。
⼀个抽象类⾃⾝⽆法实例化,也就是说我们⽆法定义⼀个抽象类的对象,只能通过继承机制,⽣成抽象类的⾮抽象派⽣类,然后再实例化。
抽象类是带有纯虚函数的类。
纯虚函数是⼀个基类中说明的虚函数,它在该基类中没有定义具体的操作内容,要求各派⽣类必须根据实际需要定义⾃⼰的版本,纯虚函数的声明格式为:virtual 函数类型函数名(参数表)= 0;声明为纯虚函数之后,基类中就不再给出函数的实现部分,它的实现是在它的派⽣类定义的。
对抽象类使⽤的⼏点规定如下:1 抽象类只能⽤作其他类的基类,不能建⽴抽象类对象;2 抽象类不能⽤作参数类型、函数返回类型或显式转换的类型;3 可以说明指向抽象类的指针和引⽤,此指针可以指向它的派⽣类,进⽽实现多态性⼀般虚函数成员的定义语法是:virtual 函数类型函数名(形参表)纯虚函数的声明格式为:virtual 函数类型函数名(参数表)= 0;三、程序例题例题有⼀个汽车类Vehicle,将它作为基类派⽣出⼩车类Car、卡车为类Truck和轮船类Boat,定义message( )函数⽤来显⽰各类信息。
实验五 虚函数与多态性
实验五虚函数与多态性一、实验目的与要求(1)学习虚函数和纯虚函数的定义与使用方式。
(2)理解抽象类的概念,学习如何用指针指向其他的派生类,实现多态性。
(3)掌握抽象类的定义与使用方式,并注意指针的用法。
(4)学习如何使用虚函数、纯虚函数、抽象类和实现类的多态性。
二、实验设备与平台实验设备要求每个学生一台电脑,其中运行环境为VC++ 6.0系统。
三、实验内容与步骤实验1、虚函数的简单使用。
# include <iostream.h >class base{public:v irtual void fh() {cout << "In base class \n " ; }};class subclass: public base{public:v irtual void fn() { cout << "In subclass \n " ; }};void test( base &b){ b.fh(); }void main( ){b ase be;s ubclass sc;c out << " Calling test(bc) \n" ;t est(be);c out << "Calling test(sc) \n " ;t est(sc);}实验2、用抽象类实现的菜单程序。
#include < iostream.h >class Menu{public:virtual void action ( ) = 0;};class item1: public Menu{public:virtual void action (){cout<< "新建文件" << endl;}};class item2: public Menu{public :virtual void action ( ){cout<< "打开文件 " << endl;}};class item3: public Menu{public:virtual void action ( ){cout << "保存文件" <<endl;}};class item4: public Menu{public:virtual void action(){cout << "关闭文件" << endl;}};void main(){ int select;Menu * Fptr[4];Fptr[0] = new item1;Fptr[1] = new item2;Fptr[2] = new item3;Fptr[3] = new item4;do{cout << " 1 new file " << endl;cout << " 2 open file " << endl;cout << " 3 save file " << endl;cout << "4 close file " << endl;cout << "0 exit " << endl;cin >> select;if( select >= 1 && select <= 4)Fptr[select-1]->action();}while( select!= 0 ) ;for ( int i = 0 ; i <= 3 ; i++ ){ delete Fptr[i]; }}实验3:定义一个从正方形、球体和圆柱体的各种运算中抽象出一个公共基 container类,在其中定义表面积和体积的纯虚函数,在抽象类中定义一个公共的成员数据radius,此数据可作为球体的半径,正方形的边长,圆柱体的底面的半径。
C实验报告-实验5多态性与虚函数
实验5 多态性与虚函数一、实验目的和要求了解静态联编和动态联编的概念。
掌握动态联编的条件。
二、实验内容和原理事先编写好程序,上机调试和运行程序,分析结果。
(1)实验指导书P96 1~4任选一题。
(2)实验指导书P100 5~6任选一题。
三、实验环境联想计算机,Windows XP操作系统,Visual C++ 6.0四、算法描述及实验步骤(1)编写源程序。
(2)检查程序有无错误(包括语法错误和逻辑错误),有则改之。
(3)编译和连接,仔细分析编译信息,如有错误应找出原因并改正之。
(4)运行程序,分析结果。
(5)将调试好的程序保存在自己的用户目录中,文件名自定。
五、调试过程12六、实验结果15七、总结动态联编需要满足3个条件,首先类之间满足类型兼容规则;第二是要声明虚函数;第三是要由成员函数来调用或者是通过基类指针、引用来访问虚函数。
附录:1.public:virtual void f(float x){cout<<"Base::f(float)"<<x<<endl;} void g(float x){cout<<"Base::g(float)"<<x<<endl;}void h(float x ){cout<<"Base::h(float)"<<x<<endl;} };class Derived:public Base{public:virtual void f(float x){cout<<"Derived::h(float)"<<x<<endl;}};int main(){Derived d;Base * pb=&d;Derived *pd=&d;pb->f(3.14f);pb->f(3.14f);pb->g(3.14f);pb->h(3.14f);pb->h(3.14f);return 0;}2#include<iostream>using namespace std;#include<string>class Teacher{public:Teacher(string n,int h);virtual double salary()=0;virtual void print()=0;protected:string name;int lessons;};Teacher::Teacher(string n,int h){name=n;lessons=h;}class Professor:public Teacher{public:Professor(string n,int h):Teacher(n,h){}double salary(){return 5000 + 50 * lessons;}void print();void Professor::print(){cout<<name<<"\tProfessor\t\t"<<lessons<<"lessons"; cout<<"\tearned ¥"<<salary()<<endl;}class Associateprofessor:public Teacher{public:Associateprofessor(string n,int h):Teacher(n,h){}double salary(){return 3000+30*lessons;}void print();};void Associateprofessor::print(){cout<<na#include<iostream>using namespace std;#include<string>class Teacher{public:Teacher(string n,int h);virtual double salary()=0;virtual void print()=0;protected:string name;int lessons;};Teacher::Teacher(string n,int h){name=n;lessons=h;}class Professor:public Teacher{public:Professor(string n,int h):Teacher(n,h){}double salary(){return 5000 + 50 * lessons;}void print();};void Professor::print(){cout<<name<<"\tProfessor\t\t"<<lessons<<"lessons"; cout<<"\tearned ¥"<<salary()<<endl;}class Associateprofessor:public Teacher{public:Associateprofessor(string n,int h):Teacher(n,h){}double salary(){return 3000+30*lessons;}void print();};void Ass me<<"\tAssociateprofessor\t"<<lessons<<"lessons"; cout<<"\tearned ¥"<<salary()<<endl;}class Lecturer:public Teacher{public:Lecturer(string n,int h):Teacher(n,h){}double salary(){return 2000+20*lessons;}void print();};void Lecturer::print(){cout<<name<<"\tLecturer\t\t"<<lessons<<"lessons";cout<<"\tearned ¥"<<salary()<<endl;}int main(){Teacher * t[3];t[0]=new Professor("Tang XiHua",12);t[1]=new Associateprofessor("Li HanPin",16);t[2]=new Lecturer("Zhang Y ue",20);for(int i=0;i<3;i++){t[i]->print();delete t[i];}return 0;}。
实验报告6 纸质
实验六多态性一、实验目的1. 掌握运算符重载的方法;2. 学习使用虚函数实现动态多态性。
二、实验内容1. 声明 Point 类,有坐标_x,_y 两个成员变量;对 Point 类重载“++”(自增)、“--”(自减)运算符,实现对坐标值的改变。
2. 声明一个车(vehicle)基类,有 Run、Stop 等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类,从 bicycle 和 motorcar 派生出摩托车(motorcycle)类,它们都有 Run、Stop 等成员函数。
观察虚函数的作用。
3.编一带派生类的程序,用虚函数多态性计算三角形、正方形和圆形的面积,并编写主程序测试。
三、实验仪器、设备C++对机器运行要求不高,给出基于Windows 平台的机器要求:硬件要求:CPU PII 以上,128M 内存,1OOM 硬盘空间即可。
软件要求:VC++ 6.0。
四、实验报告1.源代码:#include <iostream>using namespace std;class Point {public:Point(int x = 0, int y = 0);Point &operator ++();Point operator ++(int);Point &operator --();Point operator --(int);void display();private:int _x;int _y;};Point::Point(int x, int y) {_x = x;_y = y;}void Point::display() {cout << _x << "," << _y << endl; }Point &Point::operator ++() {_x++;_y++;return *this;}Point Point::operator ++(int) { Point old = *this;++(*this);return old;}Point &Point::operator --() { _x--;_y--;return *this;}Point Point::operator --(int) { Point old = *this;--(*this);return old;}int main(void) {Point point(3, 4);cout << "初始坐标:";point.display();cout << "point++坐标:";(point++).display();cout << "++point坐标:";(++point).display();cout << "point--坐标:";(point--).display();cout << "--point坐标:";(--point).display();return 0;}运行结果:2.源代码:#include<iostream>using namespace std;class vehicle{public :virtual void Run(){cout<<"vehicle Run!"<<endl;}virtual void Stop(){cout<<"vehicle Stop!"<<endl;} };class bicycle: public vehicle{public:void Run(){cout<<"bicycle Run!"<<endl;}void Stop(){cout<<"bicycle Stop!"<<endl;} };class motorcar: virtual public vehicle{public:void Run(){cout<<"motorcar Run!"<<endl;}void Stop(){cout<<"motorcar Stop!"<<endl;}};class motorcycle: public bicycle,public motorcar{ public:void Run(){cout<<"motorcycle Run!"<<endl;} void Stop(){cout<<"motorcycle Stop!"<<endl;} };void display(vehicle *ptr){ptr->Run();ptr->Stop();cout<<endl;}int main() {vehicle p1;bicycle p2;motorcar p3;motorcycle moto;display(&p1);display(&p2);display(&p3);moto.Run();moto.Stop();return 0;}运行结果:3.源代码:#include <iostream>#include <cmath>using namespace std;class base {protected:int x;int y;int z;public:base(int x, int y, int z) {base::x = x;base::y = y;base::z = z;}virtual float display() {cout << "这个类没有面积" << endl;return 0;}};class rectangle:public base {public:rectangle(int x, int y):base(x, y, z = 0) {}float display() {return x * y;}};class triangle:public base {public:triangle(int x, int y, int z):base(x, y, z) {}float display() {float p = (x + y + z) / 2;float s = sqrt(p * (p - x) * (p - y) * (p - z));return s;}};class circle:public base {public:circle(int x): base(x, 0, 0) {}float display() {return x * x * 3.1415;}};int main(void) {base *p;triangle t(3, 4, 5);rectangle r(4, 5);circle c(5);p = &t;cout << "三角形面积:" << p->display() << endl;p = &r;cout << "矩形面积:" << p->display() << endl;p = &c;cout << "圆形面积" << p->display() << endl;return 0;}运行结果:实验总结本次实验主要是学习虚函数的使用,运算符重载最主要就是要使用虚函数来实现多态,还有就是抽象类不能实例化,通过本次实验,我学到了很多东西,但是还远远没有达到掌握的目的。
实验6多态性与虚函数
[实验目的]1、了解多态性的概念;2、了解虚函数的用途及使用方法;3、了解纯虚函数和抽象类的概念和用法。
[实验要求]给出以下各实验内容的源程序代码,并把编译、运行过程中出现的问题以及解决方法填入实验报告中,按时上交。
[实验学时]2学时。
[实验内容]1、写一个程序,定义抽象基类Shape,由它派生出3个派生类:Circle(圆形)、Square(正方形)、Rectangle(矩形)。
利用指针、虚函数printArea()分别输出以上三者的面积,3个图形的数据在定义对象时给定。
[源程序]#include<iostream>using namespace std;class Shape{public:virtual float area()const=0;virtual void display()const=0;};class Circle:public Shape{public:Circle(double a):r(a){}virtual float area()const{return 3.14*r*r;}virtual void display()const{cout<<"圆面积"<<area()<<endl;}private:double r;};class Rectangle:public Shape{public:Rectangle(double a,double b):l(a),w(b){}virtual float area()const{return l*w;}virtual void display()const{cout<<"矩形面积"<<area()<<endl;}private:double l;double w;};class Square:public Shape{public:Square(double a):a1(a){}virtual float area()const{return a1*a1;}virtual void display()const{cout<<"正方形面积"<<area()<<endl;}private:double a1;};int main(){Circle c1(5);Rectangle r1(5,8);Square s1(2.5);Shape *p[3]={&c1,&r1,&s1};int i;double m=0.0;for (i=0;i<3;i++){p[i]->display();m=m+p[i]->area();}cout<<"总面积:"<<m<<endl;}2、定义Point(点)类,由Point类派生出Circle(圆)类,再由Circle类派生出Cylinder(圆柱体)类。
实验三 多态与虚函数
C++与数据结构实验指导书实验三多态与虚函数一、实验目的1、理解多态的概念;2、理解函数的静态联编和动态联编;3、掌握虚函数的使用方法;4、掌握抽象类的概念及使用方法。
二、实验内容虚函数是在类中被声明为virtual的成员函数,当编译器看到通过指针或引用调用此类函数时,对其执行动态联编,即通过指针(或引用)指向的类的类型信息来决定该函数是哪个类的。
通常此类指针或引用都声明为基类的,它可以指向基类或派生类的对象。
多态指同一个方法根据其所属的不同对象可以有不同的行为。
虚函数是C++中用于实现多态(polymorphism)的机制。
核心理念就是通过基类访问派生类定义的函数1、录入下面程序,并分析结果:#include <iostream>#include <complex>using namespace std;class Base{public:Base() {cout<<"Base-ctor"<<endl;}~Base() {cout<<"Base-dtor"<<endl;}virtual void f(int){cout<<"Base::f(int)"<<endl;}virtual void f(double){cout<<"Base::f(double)"<<endl;}virtual void g(int i=10){cout<<"Base::g()"<<i<<endl;} };class Derived : public Base{public:Derived() {cout<<"Derived-ctor" <<endl;} ~Derived(){cout<<"Derived-dtor"<<endl;}void f(complex<double>) {cout<<"Derived::f(complex)"<<endl;}void g(int i=20){cout<<"Derived::g()"<<i<<endl;}};int main(){cout<<sizeof(Base)<<endl;cout<<sizeof(Derived)<<endl;Base b;Derived d;Base *pb=new Derived;b.f(1.0);d.f(1.0);pb->f(1.0);b.g();d.g();pb->g();delete pb;return 0;}2、录入下面程序,分析运行结果:#include <iostream>using namespace std;class Base{public:Base():data(count){cout<<"Base-ctor"<<endl;++count;}~Base(){cout<<"Base-dtor"<<endl;--count;}static int count;int data;};int Base::count;class Derived : public Base{public:Derived():data(count),data1(data){cout<<"Derived-ctor"<<endl;++count;}~Derived(){cout<<"Derived-dtor"<<endl;--count;}static int count;int data1;int data;};int Derived::count=10;int main(){cout<<sizeof(Base)<<endl;cout<<sizeof(Derived)<<endl;Base* pb = new Derived[3];cout<<pb[2].data<<endl;cout<<((static_cast<Derived*>(pb))+2)->data1<<endl;delete[] pb;cout<<Base::count<<endl;cout<<Derived::count<<endl;return 0;}3、录入下面程序,分析编译错误信息。
实验五 虚函数与多态性
实验五 虚函数与多态性(4学时)[实验目的]1、 掌握运算符重载的基本方法;掌握虚函数的定义与使用方法。
2、 理解静态多态性和动态多态性;掌握使用虚函数和继承实现动态多态性的方法。
[实验内容与步骤]1、 定义Pomt 类,包含有坐标x ,y 两个成员变量,对Pomt 类重载运算符 ++(功能:坐标值x ,y 增1)和 --(功能:坐标值x ,y 减1),实现对坐标值的增减。
2、 定义一个车(vehicle )基类,有Run 、Stop 等成员函数,由此派生出自行车(bicycle )类、汽车(motorcar )类,从vehicle 和motorcar 派生出摩托车(motorcycle )类,它们都有Run 、Stop 等成员函数。
观察虚函数的作用。
3、 对实验三中的people 类重载运算符 == 和 = 。
其中,== 用于判断两个people 类对象的id 属性是否相等;= 则实现对people 类对象的赋值操作。
4、 定义矩阵类,重载运算符 + 和 *,实现对矩阵类对象的相加和相乘。
5、 定义一个类BaseFly ,该类中有一个 Fly ()函数。
再定义三个类 BirdFly 、DragonFly 和 PlaneFly ,都继承自 BaseFly ,并重载 Fly ()函数。
用各类指针调用各个类对象的 Fly ()函数,体会继承的多态性。
6、 将 BaseFly ∷Fly( ) 函数声明为 virtual ,体会虚函数在多态性中的作用。
[习题与思考题]1、 建立一个类 convert ,它含有两个私有数据成员 x 与 y ,用于表示直角坐标的位置;另外含有两个私有成员函数getr( )与 getangle( ),用于将直角坐标转换为极坐标。
重载运算符 +,使能执行convert 类对象的相加运算。
直角坐标(x ,y )转换为极坐标(r ,θ)的公式为:πθ180tan 122⨯=+=-x y y x r , 2、 创建字符串类string ,重载运算符 +,使能实现两个字符串的连接;重载运算符 =,使能实现字符串赋值。
c++实验多态性实验报告
c++实验多态性实验报告C++实验多态性实验报告一、实验目的本次实验的主要目的是深入理解和掌握 C++中的多态性概念及其实现方式。
通过实际编程和运行代码,体会多态性在面向对象编程中的重要作用,提高编程能力和对 C++语言特性的运用水平。
二、实验环境本次实验使用的编程环境为 Visual Studio 2019,操作系统为Windows 10。
三、实验内容(一)虚函数1、定义一个基类`Shape`,其中包含一个虚函数`area()`用于计算图形的面积。
2、派生类`Circle` 和`Rectangle` 分别重写`area()`函数来计算圆形和矩形的面积。
(二)纯虚函数1、定义一个抽象基类`Vehicle`,其中包含一个纯虚函数`move()`。
2、派生类`Car` 和`Bicycle` 分别实现`move()`函数来描述汽车和自行车的移动方式。
(三)动态多态性1、创建一个基类指针数组,分别指向不同的派生类对象。
2、通过基类指针调用虚函数,观察多态性的效果。
四、实验步骤(一)虚函数实现1、定义基类`Shape` 如下:```cppclass Shape {public:virtual double area()= 0;};```2、派生类`Circle` 的定义及`area()`函数的实现:```cppclass Circle : public Shape {private:double radius;public:Circle(double r) : radius(r) {}double area(){return 314 radius radius;}};```3、派生类`Rectangle` 的定义及`area()`函数的实现:```cppclass Rectangle : public Shape {private:double length, width;public:Rectangle(double l, double w) : length(l), width(w) {}double area(){return length width;}```(二)纯虚函数实现1、定义抽象基类`Vehicle` 如下:```cppclass Vehicle {public:virtual void move()= 0;};```2、派生类`Car` 的定义及`move()`函数的实现:```cppclass Car : public Vehicle {public:void move(){std::cout <<"Car is moving on the road"<< std::endl;}};3、派生类`Bicycle` 的定义及`move()`函数的实现:```cppclass Bicycle : public Vehicle {public:void move(){std::cout <<"Bicycle is moving on the path"<< std::endl;}};```(三)动态多态性实现1、创建基类指针数组并指向不同的派生类对象:```cppShape shapes2;shapes0 = new Circle(50);shapes1 = new Rectangle(40, 60);```2、通过基类指针调用虚函数:```cppfor (int i = 0; i < 2; i++){std::cout <<"Area: "<< shapesi>area()<< std::endl;}```五、实验结果(一)虚函数实验结果运行程序后,能够正确计算出圆形和矩形的面积,并输出到控制台。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
淮海工学院计算机科学系实验报告书课程名:《 C++程序设计(二)》题目:多态性和虚函数班级:学号:姓名:1、实验内容或题目(1)声明二维坐标类作为基类派生圆的类,把派生类圆作为基类,派生圆柱体类。
其中,基类二维坐标类有成员数据:x、y坐标值;有成员函数:构造函数实现对基类成员数据的初始化、输出的成员函数,要求输出坐标位置。
派生类圆类有新增成员数据:半径(R);有成员函数:构造函数实现对成员数据的初始化、计算圆面积的成员函数、输出半径的成员函数。
派生圆柱体类新增数据有高(H);新增成员函数有:构造函数、计算圆柱体体积的函数和输出所有成员的函数。
请完成程序代码的编写、调试。
(2)教材393页7-8题。
(3)教材416页1、4、5题。
2、实验目的与要求(1)理解继承与派生的概念(2)掌握通过继承派生出一个新的类的方法(3)了解多态性的概念(4)了解虚函数的作用与使用方法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;}float getY() const {return y;}friend ostream & operator<<(ostream &,const Point &); protected:float x,y;};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){cout<<"["<<p.x<<","<<p.y<<"]"<<endl;return output;}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::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){cout<<"Center=["<<c.x<<","<<c.y<<"], r="<<c.radius<<", area="<<c.area()<<endl;return output;}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::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){cout<<"Center=["<<cy.x<<","<<cy.y<<"], r="<<cy.radius<<", h="<<cy.height <<"\narea="<<cy.area()<<", volume="<<cy.volume()<<endl;return output;}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.(1)#include <iostream>using namespace std;class A{public:A(){a=0;b=0;}A(int i){a=i;b=0;}A(int i,int j){a=i;b=j;}void display(){cout<<"a="<<a<<" b="<<b;} private:int a;int b;};class B : public A{public:B(){c=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: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();return 0;}(2)#include <iostream>using namespace std;class A{public:A(){cout<<"constructing A "<<endl;} ~A(){cout<<"destructing A "<<endl;} };class B : public A{public:B(){cout<<"constructing B "<<endl;} ~B(){cout<<"destructing B "<<endl;} };class C : public B{public:C(){cout<<"constructing C "<<endl;}~C(){cout<<"destructing C "<<endl;}};int main(){C c1;return 0;}3.(1)//Point.hclass 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:float x,y;}//Point.cppPoint::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){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.cppCircle::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<<"], r="<<c.radius<<", area="<<c.area()<<endl;return output;}//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.cppCylinder::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<<"\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;class Circle:public Shape{public:Circle(double r):radius(r){} virtual double area() const {return 3.14159*radius*radius;}; protected:double radius;};class Rectangle:public Shape{public:Rectangle(double w,double h):width(w),height(h){} virtual double area() const {return width*height;} protected:double width,height; };class Triangle:public Shape{public:Triangle(double w,double h):width(w),height(h){} virtual double area() const {return 0.5*width*height;} protected:double width,height; };void printArea(const Shape &s)cout<<s.area()<<endl;} int main(){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;}(3)#include <iostream>using namespace std;class Shape{public:virtual double area() const =0;};class Circle:public Shape{public:Circle(double r):radius(r){}virtual double area() const {return 3.14159*radius*radius;}; protected:double radius;class Square:public Shape{public:Square(double s):side(s){}virtual double area() const {return side*side;}protected:double side;};class Rectangle:public Shape{public:Rectangle(double w,double h):width(w),height(h){}virtual double area() const {return width*height;}protected:double width,height; };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;} protected:double top,bottom,height;};class Triangle:public Shapepublic:Triangle(double w,double h):width(w),height(h){}virtual double area() const {return 0.5*width*height;} protected:double width,height;};int main(){Circle circle(12.6);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 *pt[5]={&circle,&square,&rectangle,&trapezoid,&triangle};double areas=0.0;for(int i=0;i<5;i++){areas=areas+pt[i]->area();}cout<<"totol of all areas="<<areas<<endl;return 0;}4、测试数据与实验结果(可以抓图粘贴)5、结果分析与实验体会继承时,子类对基类的访问属性,基类的私有成员无论以何种方式继承在子类中都是不可访问的,唯有调用基类中的成员函数方可访问其私有变量。