实验4-多态性与虚函数
- 格式:doc
- 大小:194.00 KB
- 文档页数:10
一.实验目的及要求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;}五.实验总结通过本次试验 我更深刻的理解了某些语句如何使用及结构体的优点 也能更加熟练的编写简单的程序了 我深知实践要比书本更加重要 今后还要多练习 在实践中学习。
贵州大学实验报告学院:电子信息学院专业:通信工程班级:实验内容1. 编写4个重载函数Double(x),返回值为输入参数的两倍;参数类型分别为int、long、float、double,返回值类型与参数类型一样。
2.请编写一个抽象类Shape,在此基础上派生出类Rectangle和Circle,二者都有计算对象面积的函数GetArea()和计算周长函数GetPerim()。
3.对类Point重载++(自增)、--(自减)运算符。
实验数据1、代码如下:#include<iostream>using namespace std;int Double(int x);long Double(long x);float Double(float x);double Double(double x);int main(){ int myInt = 6500;cout<<Double(myInt)<<endl;long myLong = 65000;cout<<Double(myLong)<<endl;float myFloat = 6.5F;cout<<Double(myFloat)<<endl;double myDouble = 6.5e20;cout<<Double(myDouble)<<endl;}int Double(int x) { return 2*x;}long Double(long x) { return 2*x;}float Double(float x) { return 2*x;}double Double(double x) { return 2*x;}运行结果:2、代码:#include<iostream>#define PI 3.1415926;using namespace std;class Shape //抽象类的定义{public:virtual double GetArea() = 0; //纯虚函数cin >> length >> width;Rectangle rect(length, width);cout << "面积是:"<< rect.GetArea() << endl<<"周长是:"<<rect.GetPerim()<<endl; double rr;cout << "输入半径: ";cin >> rr;Circle cir(rr);cout << "面积是:"<<cir.GetArea() << endl<<"周长是:"<<cir.GetPerim()<<endl;}运行结果:3、代码如下:#include<iostream.h>class Point{public:Point(int xx,int yy):x(xx),y(yy) {}void display()const;Point &operator++();Point operator++(int);Point &operator--();Point operator--(int);private:int x,y;};void Point::display()const{cout<<"当前Point("<<x<<","<<y<<")"<<endl;}Point &Point::operator++(){x++;y++;cout<<"执行x++,y++操作!"<<endl;return *this;}Point Point::operator++(int){cout<<"执行++x,++y操作!"<<endl;return Point(++x,++y);}Point &Point::operator--(){x--;y--;cout<<"执行x--,y--操作!"<<endl; return *this;}Point Point::operator--(int){cout<<"执行--x,--y操作!"<<endl; return Point(--x,--y);}int main(){int x,y;cout<<"Input x&y:";cin>>x>>y;Point point1(x,y);point1.display();point1++;point1.display();++point1;point1.display();point1--;point1.display();--point1;point1.display();return 0;}运行结果:注:各学院可根据教学需要对以上栏木进行增减。
多态性与虚函数1.概念填空题1.1 C++支持两种多态性,分别是编译时和运行时。
1.2在编译时就确定的函数调用称为静态联编,它通过使用函数重载,模板等实现。
1.3在运行时才确定的函数调用称为动态联编,它通过虚函数来实现。
1.4虚函数的声明方法是在函数原型前加上关键字virtual。
在基类中含有虚函数,在派生类中的函数没有显式写出virtual关键字,系统依据以下规则判断派生类的这个函数是否是虚函数:该函数是否和基类的虚函数同名;是否与基类的虚函数参数个数相同、类型;是否与基类的虚函数相同返回类型。
如果满足上述3个条件,派生类的函数就是虚函数。
并且该函数覆盖基类的虚函数。
1.5 纯虚函数是一种特别的虚函数,它没有函数的函数体部分,也没有为函数的功能提供实现的代码,它的实现版本必须由派生类给出,因此纯虚函数不能是友元函数。
拥有纯虚函数的类就是抽象类类,这种类不能实例化。
如果纯虚函数没有被重载,则派生类将继承此纯虚函数,即该派生类也是抽象。
3.选择题3.1在C++中,要实现动态联编,必须使用(D)调用虚函数。
A.类名B.派生类指针C.对象名D.基类指针3.2下列函数中,不能说明为虚函数的是(C)。
A.私有成员函数B.公有成员函数C.构造函数D.析构函数3.3在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值(A)。
A.相同B.不同C.相容D.部分相同3.4当一个类的某个函数被说明为virtual时,该函数在该类的所有派生类中(A)。
A.都是虚函数B.只有被重新说明时才是虚函数C.只有被重新说明为virtual时才是虚函数D.都不是虚函数3.5(C)是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。
A.虚析构函数B.虚构造函数C.纯虚函数D.静态成员函数3.6 以下基类中的成员函数,哪个表示纯虚函数(C)。
A.virtual void vf(int);B.void vf(int)=0;C.virtual void vf( )=0;D.virtual void vf(int){ }3.7下列描述中,(D)是抽象类的特性。
实验四虚函数与多态性实验目的和要求 :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)抽象类:抽象类是一种特殊的类。
抽象类是为了抽象和设计的目的而建立的。
一个抽象类自身无法实例化,也就是说无法定义一个抽象类的对象,只能通过继承机制,生成抽象类的非抽象派生类,然后再实例化。
多态性与虚函数实验报告实验目的:通过实验掌握多态性和虚函数的概念及使用方法,理解多态性实现原理和虚函数的应用场景。
实验原理:1.多态性:多态性是指在面向对象编程中,同一种行为或者方法可以具有多种不同形态的能力。
它是面向对象编程的核心特性之一,能够提供更加灵活和可扩展的代码结构。
多态性主要通过继承和接口来实现。
继承是指子类可以重写父类的方法,实现自己的特定行为;接口是一种约束,定义了类应该实现的方法和属性。
2.虚函数:虚函数是在基类中声明的函数,它可以在派生类中被重新定义,以实现多态性。
在类的成员函数前面加上virtual关键字,就可以将它定义为虚函数。
当使用基类指针或引用调用虚函数时,实际调用的是派生类的重写函数。
实验步骤:1. 创建一个基类Shape,包含两个成员变量color和area,并声明一个虚函数printArea(用于打印面积。
2. 创建三个派生类Circle、Rectangle和Triangle,分别继承Shape类,并重写printArea(函数。
3. 在主函数中,通过基类指针分别指向派生类的对象,并调用printArea(函数,观察多态性的效果。
实验结果与分析:在实验中,通过创建Shape类和派生类Circle、Rectangle和Triangle,可以实现对不同形状图形面积的计算和打印。
当使用基类指针调用printArea(函数时,实际调用的是派生类的重写函数,而不是基类的函数。
这就是多态性的实现,通过基类指针或引用,能够调用不同对象的同名函数,实现了对不同对象的统一操作。
通过实验1.提高代码的可扩展性和灵活性:通过多态性,可以将一类具有相似功能的对象统一管理,节省了代码的重复编写和修改成本,增强了代码的可扩展性和灵活性。
2.简化代码结构:通过虚函数,可以将各个派生类的不同行为统一命名为同一个函数,简化了代码结构,提高了代码的可读性和维护性。
3.支持动态绑定:通过运行时的动态绑定,可以根据对象的实际类型来确定调用的函数,实现了动态绑定和多态性。
《C++面向对象程序设计》实验内容实验1 C++程序设计初步1.实验目的(1)了解在C++编译系统(Visual C++6.0)上如何编辑、编译、连接和运行一个C++程序。
(2)通过运行简单的C++程序, 初步了解C++源程序的结构和特点。
(3)掌握简单C++程序的编写和调试方法。
(4)掌握重载函数的定义方法。
(5)能正确使用引用型变量。
2.实验内容和步骤(1)在Visual C++环境下编译和运行C++程序①先进入Visual C++6.0环境。
②在自己指定的子目录中建立一个名为test.cpp的新文件。
③从键盘输入以下程序int main(){int a,b;c=a+b;cout>> “a+b=”>>a+b;}选择Build→Compile test.cpp命令, 对此源程序进行编译。
观察和分析编译信息。
⑤根据编译信息指出的错误, 修改程序。
再进行编译, 如果还有错, 再重复此过程, 直到编译不出错为止。
⑥选择Build→Build test.exe命令, 对程序进行连接, 如果不出错, 就会生成可执行程序test.exe。
⑦选择Build→Execute test.exe命令, 执行可执行程序test.exe。
观察屏幕的变化。
在输出窗口应显示程序运行结果。
⑧分析结果是否正确, 如果不正确或认为输出格式不理想, 可以修改程序, 然后重新执行以上④和⑧步骤。
改过后的程序:#include<iostream>using namespace std;int add(int x,int y){int z;z=x+y;return(z);}int main(){int a,b,c;cin>>a>>b;c=add(a,b);cout<<"a+b="<<c<<endl;return 0;}实验2 C++对C的扩充(2)编一个程序, 用来求2个或3个正整数中的最大数。
淮海工学院计算机工程学院实验报告书课程名:《 C++程序设计(2) 》题目:多态性与虚函数班级:网络111学号:2011122525姓名:张洋1、实验内容或题目(1)分析调试教材p402页例12.2,将基类成员函数改为虚函数,理解虚函数的作用;(2) P416习题1(参考P258“类的声明和成员函数定义的分离”介绍)、编程实现;(3)习题4,编程实现。
2、实验目的与要求(1)了解多态性的概念;(2)了解虚函数的作用及使用方法;(3)了解静态关联和动态关联的概念和方法;(4)了解纯虚函数和抽象类的概念和方法。
3、实验步骤与源程序⑴实验步骤①先声明一个基类;②由基类派生出其他类;③定义虚函数④调试;⑵源代码(只写编程题的代码)(2)//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.CPP//#include <iostream.h>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<<"], 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;}#include <iostream> //如用VC++应改为∶#include <iosttram.h>using namespace std; //如用VC++应取消此行#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;}(3)#include <iostream>using namespace std;//定义抽象基类Shapeclass Shape{public:virtual double area() const =0; //纯虚函数};//定义Circle类class Circle:public Shape{public:Circle(double r):radius(r){} //结构函数virtual double area() const {return 3.14159*radius*radius;}; //定义虚函数 protected:double radius; //半径};//定义Rectangle类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;} //输出s的面积int main(){Circle circle(12.6); //建立Circle类对象circlecout<<"area of circle =";printArea(circle); //输出circle的面积Rectangle rectangle(4.5,8.4); //建立Rectangle类对象rectanglecout<<"area of rectangle =";printArea(rectangle); //输出rectangle的面积Triangle triangle(4.5,8.4); //建立Triangle类对象cout<<"area of triangle =";printArea(triangle); //输出triangle的面积return 0;}4、测试数据与实验结果(可以抓图粘贴,提交所有题目的结果。