c++-chap-12-多态性和虚函数.ppt_第1页
c++-chap-12-多态性和虚函数.ppt_第2页
c++-chap-12-多态性和虚函数.ppt_第3页
c++-chap-12-多态性和虚函数.ppt_第4页
c++-chap-12-多态性和虚函数.ppt_第5页
免费预览已结束,剩余27页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

课件作者 刘葳 第12章多态性和虚函数 1 1 多态性的概念 多态性 是面向对象程序设计的重要特征 它是指对不同类的对象发出相同的消息将会有不同的实现 即对于接收相同的消息的不同类型的对象接收时可以导致完全不同的行为 谓之多态性 多态性与继承相关多态性常用重载技术与虚函数来实现多态性分为两类 静态多态性和动态多态性 2 1 多态性的概念 静态多态性 通过函数重载实现 由函数重载和运算符重载形成的多态性属于静态多态性 这种多态性是在函数编译时系统就知道要调用哪个函数了 所以也称编译时的多态性 动态多态性 不是在编译时确定调用哪个函数 而是在程序运行过程中才动态的确定操作所针对的对象 所以也称为运行时的多态性 3 2 一个典型的例子 例12 1 P393 397先建立一个Point 点 类 包含数据成员x y 坐标点 以它为基类 派生出一个Circle 圆 类 增加数据成员r 半径 再以Circle类为直接基类 派生出一个Cylinder 圆柱体 类 再增加数据成员h 高 要求写程序 重载运算符 使之能用于输出和输入以上的类的对象 注明 分若干步骤进行编写和调试 该例子中介绍的同名函数调用的方法为静态多态性 4 5 2 一个典型的例子 includeclassPoint 声明类Point public 以下是声明Point类的成员函数Point float 0 float 0 带默认值的构造函数voidsetPoint float float floatgetX const returnx floatgetY const returny friendostream 第1步 创建基类Point 编写简单的主函数使用该类 6 2 一个典型的例子 定义Point类的成员函数 Point的构造函数Point Point floata floatb x a y b 设置x和y的坐标值voidPoint setPoint floata floatb x a y b 输出点的坐标ostream 7 2 一个典型的例子 intmain Pointp 3 5 6 4 cout x p getX y p getY endl p setPoint 8 5 6 8 cout p new p endl return0 8 2 一个典型的例子 include 声明类PointclassPoint public Point float 0 float 0 voidsetPoint float float floatgetX const returnx floatgetY const returny friendostream 第2步 声明派生类Circle 9 2 一个典型的例子 定义Point类的成员函数 Point的构造函数Point Point floata floatb x a y b 设置x和y的坐标值voidPoint setPoint floata floatb x a y b 输出点的坐标ostream 10 2 一个典型的例子 classCircle publicPoint public Circle floatx 0 floaty 0 floatr 0 voidsetRadius float 设置半径floatgetRadius const 读取半径floatarea const 常成员函数求圆面积friendostream 增加的派生类Circle 11 2 一个典型的例子 Circle Circle floata floatb floatr Point a b radius r voidCircle setRadius floatr 设置半径 radius r floatCircle getRadius const returnradius 读取半径floatCircle area const 常成员函数求圆面积 return3 14159 radius radius ostream 12 2 一个典型的例子 intmain Circlec 3 5 6 4 5 2 cout originalcircle nx c getX y c getY r c getRadius area c area endl c setRadius 7 5 c setPoint 5 5 cout newcircle n c Point 13 2 一个典型的例子 includeclassPoint 基类Point public Point float 0 float 0 voidsetPoint float float floatgetX const returnx floatgetY const returny friendostream 第3步 声明Circle的派生类Cylinder 14 2 一个典型的例子 classCircle publicPoint 由点类派生出的圆类 public Circle floatx 0 floaty 0 floatr 0 voidsetRadius float floatgetRadius const floatarea const friendostream 15 2 一个典型的例子 classCylinder publicCircle public Cylinder floatx 0 floaty 0 floatr 0 floath 0 voidsetHeight float floatgetHeight const floatarea const floatvolume const friendostream 16 2 一个典型的例子 Cylinder Cylinder floata floatb floatr floath Circle a b r height h voidCylinder setHeight floath height h floatCylinder getHeight const returnheight floatCylinder area const return2 Circle area 2 3 14159 radius height floatCylinder volume const returnCircle area height ostream 17 2 一个典型的例子 intmain Cylindercy1 3 5 6 4 5 2 10 cout noriginalcylinder 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 nnewcylinder n cy1 Point 18 3 利用虚函数实现动态多态性 1 虚函数的作用在同一类中不能定义两个名字相同 参数个数和类型都相同的函数 但在类的继承层次结构中 在不同层次中 可以出现名字相同 参数个数和类型都相同而功能不同的函数 例如 Circle类中的area函数 Circle类的派生类Cylinder中的area函数 尽管名字相同 但功能不同 前者求圆的面积 后者求圆柱的表面积 为了方便访问函数 C 提出了虚函数的概念 19 3 利用虚函数实现动态多态性 2 什么是虚函数 所谓虚函数就是在基类声明函数是虚拟的 并不是实际存在的函数 然后在派生类中才真正定义此函数 在程序运行期间 用指针指向某一派生类对象 这样就能调用指针指向的派生类对象中的函数 而不会调用其他派生类中的函数 注意 虚函数的作用允许在派生类中重新定义与基类同名的函数 20 3 利用虚函数实现动态多态性 书 P399例12 2 基类和派生类中有同名函数 21 22 include includeusingnamespacestd classStudent 基类 学生类 public Student int string float voiddisplay protected intnum stringname floatscore Student Student intn stringnam floats num n name nam score s voidStudent display cout num num nname name nscore score n n 23 classGraduate publicStudent 派生类 研究生类 public Graduate int string float float voiddisplay private floatpay voidGraduate display cout num num nname name nscore score npay pay endl Graduate Graduate intn stringnam floats floatp Student n nam s pay p 24 intmain Studentstud1 1001 Li 87 5 Graduategrad1 2001 Wang 98 5 563 5 Student pt 结果 pt只调用了基类的display 函数 没有调用派生类中的display 函数 3 利用虚函数实现动态多态性 用虚函数就能解决这个问题 只修改基类为 见右图其他内容不变 25 classStudent public Student int string float virtualvoiddisplay protected intnum stringname floatscore 3 利用虚函数实现动态多态性 结论 利用虚函数virtual 和指向基类的指针pt 使用相同的形式 即pt 函数名 可以实现对基类以及该基类派生类中的相同名字函数的调用 这就是多态性 26 3 利用虚函数实现动态多态性 3 静态关联和动态关联关联 确定调用具体对象的过程成为关联静态关联 当函数重载后 通过对象名调用虚函数 在编译时即可确定其调用的虚函数属于哪一个类 这个过程成为静态关联 动态关联 用指针调用虚函数时 在编译时不能确定调用的是哪一个对象的虚函数 但在运行过程中可以确定调用的是哪一个对象的虚函数 这个过程成为动态关联 27 3 利用虚函数实现动态多态性 4 在什么情况下应该声明虚函数首先看成员函数所在的类是否为基类 然后看成员函数在类的继承后有无可能被更改功能 如果希望更改功能 一般应该将它声明为虚函数 如果成员函数在类被继承后功能无须修改 或派生类用不到该函数 则不要将它声明为虚函数 应该考虑对成员函数的调用是通过对象名还是通过基类指针或引用去访问 如果是基类指针或引用访问 就应当声明为虚函数 有时虚函数定义时 只定义函数名 函数体为空 具体功能留给派生类去添加 28 3 利用虚函数实现动态多态性 5 虚析构函数析构函数的作用是在对象撤销之前做必要的 清场 工作 当派生类的对象从内存中撤销时 一般先调用派生类的析构函数 然后调用基类的析构函数 但是 如果用new运算符建立了临时对象 若基类中有析构函数 并定义了一个指向该基类的指针变量 在程序用带指针参数的delete运算符撤销对象时 会发生一个情况 系统只执行基类的析构函数 而不执行派生类的析构函数 例12 3 基类中有非虚构函数时的执行情况 29 30 includeusingnamespacestd classP

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论