cpp多态与虚函数.doc

上传人:小** 文档编号:86975439 上传时间:2019-03-26 格式:DOC 页数:25 大小:209KB
返回 下载 相关 举报
cpp多态与虚函数.doc_第1页
第1页 / 共25页
cpp多态与虚函数.doc_第2页
第2页 / 共25页
cpp多态与虚函数.doc_第3页
第3页 / 共25页
cpp多态与虚函数.doc_第4页
第4页 / 共25页
cpp多态与虚函数.doc_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《cpp多态与虚函数.doc》由会员分享,可在线阅读,更多相关《cpp多态与虚函数.doc(25页珍藏版)》请在金锄头文库上搜索。

1、2019-3-26 多态性与虚函数25/25多态性与虚函数主要内容:静态绑定与动态绑定,多态性的概念,虚函数,纯虚函数,抽象类,类型兼容规则。静态绑定与动态绑定绑定程序自身彼此关联的过程,确定程序中的操作调用与执行该操作的代码间的关系。静态绑定绑定过程出现在编译阶段,用对象名或者类名来限定要调用的函数。动态绑定绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。静态绑定的一个例子:#includeusing namespace std;class Point public:Point(double i, double j) x=i; y=j;double Area() const

2、return 0.0; private:double x, y;class Rectangle:public Point public:Rectangle(double i, double j, double k, double l);double Area() const return w*h; private:double w,h;Rectangle:Rectangle(double i, double j, double k, double l) :Point(i,j)w=k; h=l; void fun(Point &s)coutArea=s.Area()endl; void main

3、()Rectangle rec(3.0, 5.2, 15.0, 25.0);fun(rec);运行结果:Area=0动态绑定示例:#includeusing namespace std;class Point public: Point(double i, double j) x=i; y=j; virtual double Area() const return 0.0; private:double x, y;class Rectangle:public Point public: Rectangle(double i, double j, double k, double l); vir

4、tual double Area() const return w*h; private:double w,h;Rectangle:Rectangle(double i, double j, double k, double l) :Point(i,j)w=k; h=l; void fun(Point &s)coutArea=s.Area()endl; int main()Rectangle rec(3.0, 5.2, 15.0, 25.0);fun(rec);运行结果:Area=375说明:函数void fun(Point &s)中虽然传值的实参是派生类的对象,但函数的参数是基类的引用,调用

5、的是基类中的函数。如果Area()函数不声明为虚函数,则调用哪一个Area()函数已经由前面的s决定了。如果Area()函数声明为虚函数,则编译时不能确定是调用基类中的Area()函数还是派生类的Area(),而在动态链接的过程中,通过对象与函数的结合,才能确定到底调用哪一个Area()。多态性的概念多态是面向对象程序设计的一个重要特征。如果一种语言只支持类而不支持多态,只能称其为基于对象,而不是面向对象的。利用多态性可以设计和实现一个易于扩展的系统。在C+程序设计中,多态性是指具有不同功能的函数可以共用同一个函数名,这样就可以用一个函数名调用不同功能的函数。在面向对象方法中一般是这样表述多态

6、性的:向不同的对象发送同一个消息,不同的对象在接受时会产生不同的响应(行为和方法)。即:每个对象可以用自己的方法去响应共同的消息。这里的所谓消息,就是调用函数;不同的行为就是指执行不同的函数。在C+程序设计中,在不同的类中定义了其响应消息的方法,那么使用这些类时,不必考虑它们是什么类型,只要发布消息即可。多态的分类(从系统实现角度)从系统实现的角度看,多态性分为两类:静态多态性和动态多态性。以前学过的函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能决定调用的是哪个函数,因此静态多态性又称编译时的多态性。静态多态性是通过函数的重载实现的(运算符重载实质上也是函数重载)。动态多

7、态性是在程序运行过程中才动态地确定操作所针对的对象。它又称运行时的多态性。动态多态性是通过虚函数(virtual function)实现的。要研究的问题是:当一个基类被继承为不同的派生类时,各派生类可以使用与基类成员相同的成员名,如果在运行时用同一个成员名调用类对象的成员,会调用哪个对象的成员?也就是说,通过继承而产生了相关的不同的派生类,与基类成员同名的成员在不同的派生类中有不同的含义。也可以说,多态性是“一个接口,多种方法”。一个典型的例子下面是一个承上启下的例子:一方面它是有关继承和运算符重载内容的综合应用的例子,通过这个例子可以进一步融会贯通前面所学的内容,另一方面又是作为讨论多态性的

8、一个基础用例。例1: 先建立一个Point(点)类,包含数据成员x,y(坐标点)。以它为基类,派生出一个Circle(圆)类,增加数据成员r(半径),再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类,再增加数据成员h(高)。要求编写程序,重载运算符“”,使之能用于输出以上类对象。对于一个比较大的程序,应当分成若干步骤进行。先声明基类,再声明派生类,逐级进行,分步调试。(1)声明基类Point类可写出声明基类Point的部分如下:#include /声明类Pointclass Pointpublic:Point(float x=0,float y=0); /有默认参数的构造函

9、数void setPoint(float ,float); /设置坐标值float getX( )const return x; /读x坐标float getY( )const return y; /读y坐标friend ostream & operator (ostream &,const Point &); /重载运算符“”protected : float x, y; getX和getY函数声明为常成员函数,作用是只允许函数引用类中的数据,而不允许修改它们,以保证类中数据的安全。数据成员x和y定义成受保护成员,是为了x和y可以被派生类访问,如果声明为private,则派生类不能访问。/下

10、面定义Point类的成员函数Point:Point(float a,float b) x=a;y=b; /Point的构造函数,对x,y初始化void Point:setPoint(float a,float b) x=a;y=b;/设置x和y的坐标值ostream & operator (ostream & output, const Point &p)outputp.x,p.yendl; return output; /重载运算符“”,使之能输出点的坐标以上完成了基类Point类的声明。现在要对上面写的基类声明进行调试,检查它是否有错,为此要写出main函数。实际上它是一个测试程序:int

11、 main( )Point p(3.5,6.4); /建立Point类对象pcoutx=p.getX( ),y=p.getY( )endl; /输出p的坐标值p.setPoint(8.5,6.8); /重新设置p的坐标值coutp(new):pendl; /用重载运算符“”输出p点坐标程序编译通过,运行结果为x=3.5,y=6.4p(new):8.5,6.8测试程序检查了基类中各函数的功能,以及运算符重载的作用,证明程序是正确的。(2)声明派生类Circle在上面的基础上,再写出声明派生类Circle的部分:class Circle:public Point /circle是Point类的公用

12、派生类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 &); /重载运算符“”private:float radius; /定义构造函数,对圆心坐标和半径初始化Circle:Circle(float a,float b,float r):Point(a,b),radiu

13、s(r) /设置半径值void Circle:setRadius(float r)radius=r;/读取半径值float Circle:getRadius( )const return radius;/计算圆面积float Circle:area( )constreturn 3.14159*radius*radius; /重载运算符“”,使之按规定的形式输出圆的信息ostream &operator (ostream &output,const Circle &c)outputCenter=c.x,c.y,r=c.radius,area=c.area( )endl;return output;为了测试以上Circle类的定义,可以写出下面的主函数:int main( )Circle c(3.5,6.4,5.2); /建立Circle类对象c,并给定圆心坐标和半径coutoriginal circle:nx=c.getX(), y=c.getY(),

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 管理学资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号