C++程序设计 教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数

上传人:E**** 文档编号:89381861 上传时间:2019-05-24 格式:PPT 页数:30 大小:293KB
返回 下载 相关 举报
C++程序设计  教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数_第1页
第1页 / 共30页
C++程序设计  教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数_第2页
第2页 / 共30页
C++程序设计  教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数_第3页
第3页 / 共30页
C++程序设计  教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数_第4页
第4页 / 共30页
C++程序设计  教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数_第5页
第5页 / 共30页
点击查看更多>>
资源描述

《C++程序设计 教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数》由会员分享,可在线阅读,更多相关《C++程序设计 教学课件 ppt 作者 杨长兴 刘卫国 曹岳辉 第9章 多态性和虚函数(30页珍藏版)》请在金锄头文库上搜索。

1、第9章 多态性和虚函数,9.1 多态性的概念,多态性是指不同类的对象对于同一消息的处理具有不同的实现。 多态性在C+中表现为同一形式的函数调用,可能调用不同的函数实现。从系统实现的角度看,C+的多态性分为两类,一类称为编译时刻多态性,另一类称为运行时刻多态性,也称动态多态性。,9.1.1 编译时刻的多态性,C+编译时多态性通过重载(函数重载和运算符重载)来实现 【例9.1】 编译时刻的多态性运算符重载:下面这段程序建立Data类和T_Data类,并重载运算符“+=”,使之能用于相应类对象的运算。,#include using namespace std; class Data public:

2、Data(int x=0,int y=0); /缺省构造函数 void set_xy(int x,int y); int get_X() const; int get_Y() const; long norm(); Data() ; /析构函数 Data,class T_Data:public Data public: T_Data(int x=0,int y=0,int z=0); void set_xyz(int x,int y,int z); int get_Z(); long norm(); T_Data,int main() Data d1(10,20); Data d2; T_Da

3、ta d3(10,20,30); T_Data d4; d2.set_xy(20,40); d4.set_xyz(5,10,15); cout “d1 = ( “ d1.get_X() “ , “ d1.get_Y() “ )“ endl; cout “d2 = ( “ d2.get_X() “ , “ d2.get_Y() “ )“ endl; d2 += d1; /调用Data类的重载运算符:+= cout “d3 = ( “ d3.get_X() “ , “ d3.get_Y() “ , “ ; cout d3.get_Z() “ )“ endl; cout “d4 = ( “ d4.g

4、et_X() “ , “ d4.get_Y() “ , “ ; cout d4.get_Z() “ )“ endl; d4 += d3; /调用T_Data类的重载运算符:+= ,9.1.2 运行时刻的多态性,运行时刻多态性的实现是指在程序运行过程中根据具体情况来确定调用的是哪一个函数,它是通过动态联编机制实现的,【例9.2】运行时刻的多态性 仍然用【例9.1】中定义的Data类和T_Data类,main函数如下: /* ex9_2.cpp * int main( ) Data *p; T_Data d3(10,20,30); cout norm()endl; cout“d3s norm is

5、 (d3)“d3.norm()endl; return 0; 程序运行的结果如下图。,运行时刻的多态性是面向对象的一个非常重要的特征,再来看一个在结构化编程中的例子: 【例9.3】下面这段程序是利用多分支结构编程模拟实现绘制图形的函数。 /* ex9_3.cpp * void draw(int obj_figure) switch(obj_figure) case 0: /rectangle draw_rectangle(); /cout”draw rectangle”endl; break; case 1: /triangle draw_triangle(); / cout”draw tri

6、angle”endl; break; case 2: /circle draw_circle(); /cout“draw_circle“endl; break; 这种编程方式使得程序的可维护性和可扩充性都变得很差。那么有没有更好的方法实现上述 例子?看看下面的程序段: void draw(void * f) (*f)(); ,9.2 虚函数,虚函数的作用 虚函数从表现形式看是指那些被virtual关键字修饰的成员函数。类的一个成员函数如果被说明为虚函数,表明它目前的具体实现仅是一种适用于当前类的实现,而在该类的继承层次链条中有可能重新定义这个成员函数的实现,即这个虚函数可能会被派生类的同名函数

7、所覆盖(override)。,例:使用虚函数的例子 #include using std:cout; using std:endl; class figure public: virtual void draw() /将draw()定义为虚函数 cout“draw figure“endl; ; class rectangle:public figure void draw() cout“draw rectangle“endl; ; class triangle:public figure void draw() cout“draw triangle“endl; ;,int main() fig

8、ure *f; rectangle r1; triangle t1; f= 程序运行结果:,虚函数的使用 虚函数的实现机制和调用方式与非虚函数不同,虚函数的使用需要注意以下几点: 1虚函数的声明 只能将类的成员函数声明为虚函数,而不能将类外的普通函数声明为虚函数。虚函数的作用是允许在派生类中对基类的虚函数重新定义,因而它只能用于类的继承层次结构中。 2虚函数的访问权限 派生类中虚函数的访问权限并不影响虚函数的动态联编,如下面的例9.5,其中派生类CDerived中重新定义了虚函数F4(),在程序的运行中由于虚函数的机制,在CBase:F3()中调用F4()时会调用CDerived:F4(),而

9、该函数的访问权限是私有的。 3成员函数中调用虚函数 在类的成员函数中可以直接调用相应类中定义或重新定义的虚函数,分析这类函数的调用次序时要注意成员函数的调用一般是隐式调用,应该将其看成是通过this指针的显式调用。,【例9.5】 在成员函数中调用虚函数 / * ex9_5.cpp * #include using namespace std; class CBase public: void F1() coutCBase-F1=“; F2(); void F2() cout“; F3(); virtual void F3() cout“; F4(); /即this-F4() virtual v

10、oid F4() cout“; ;,class CDerived:public CBase private: virtual void F4() coutout“Derived-F1=“; CBase:F2(); void F2() coutDerived-F2=“; F3(); /即this-F3() ; int main() CBase *pB; CDerived Obj; 程序运行结果: pB= ,9.3 纯虚函数与抽象类,纯虚函数 在程序设计中,通常会在类层次的顶层以虚函数的形式给出该类层次所提供的某些操作的统一接口,由于层次较高,有些操作无法(也无必要)给出具体的实现,对于这种情况可

11、以不对虚函数的实现进行定义,而将它们说明为纯虚函数。纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式是: virtual (参数表列)=0;,抽象类 具有纯虚函数的类无法用于创建对象,因为它的纯虚函数无函数体,所以又把这种含有纯虚函数的类称为抽象类。抽象类的主要作用是为一个族类提供统一的公共接口,用户在这个基础上根据自己的需要定义出功能各异的派生类,以有效地发挥多态的特性。,使用抽象类时应注意以下问题: 抽象类只能用作其它类的基类,不能建立抽象类的对象。因为它的纯虚函数没有定义功能。 抽象类不能用作参数类型、函数的返回类型或显式转换的类型。 可以声明抽象类的指针和引用,通

12、过它们,可以指向并访问派生类对象,从而访问派生类的成员。 如果在抽象类所派生出的新类中对基类的所有纯虚函数进行了定义,那么这些函数就被赋予了功能,可以被调用。这个派生类就不是抽象类,而是可以用来定义对象的具体类。如果在派生类中没有对所有纯虚函数进行定义,则此派生类仍然是抽象类,不能用来定义对象。,9.4 抽象类的实例,一个抽象类就是一个界面。类层次结构是一种逐步递增地建立类的方式。有些抽象类也提供了重要的功能,支持进一步向上构造。类层次结构中的各个类一方面为用户提供了有用的功能,同时也作为实现更高级或者更特殊的类的构造块。这种层次结构对于支持以逐步求精方式进行的程序设计是非常理想的。,【例9.

13、10】抽象类实例 #include using namespace std; class CShape /定义为一个抽象类,即一个图形界面接口 public: virtual double area() const return 0.0; /定义为虚函数,允许后面覆盖 virtual void printShapeName() const=0;/定义为纯虚函数,由派生类负责实现 virtual void draw() const=0; /定义为纯虚函数 ;,class CPoint:public CShape /公有继承CShape public: CPoint(int=0,int=0); /

14、声明构造函数 void setPoint(int,int); int getX() const return x; int getY() const return y; virtual void printShapeName() const /覆盖CShape基类的纯虚函数 cout“Point:“; virtual void draw() const; private: int x,y; ;,CPoint:CPoint(int a,int b) /CPoint构造函数的实现 setPoint(a,b); void CPoint:setPoint(int a,int b) x=a; y=b;

15、void CPoint:draw() const cout“x“, “y“;,class CCircle:public CPoint public: CCircle(double r=0.0, int x=0,int y=0); void setRadius(double) ; double getRadius() const; virtual double area() const; virtual void printShapeName() const cout“Circle:“; virtual void draw() const; private: double radius; ;,CCircle:CCircle(double r,int a,int b):CPoint(a,b) setRadius(r); void CCircle:setRadius(double r) radius=r0?r:0; double CCircle:getRadius()

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

当前位置:首页 > 高等教育 > 大学课件

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