




已阅读5页,还剩32页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第14章多态 2 本章内容安排 多态的概念虚函数实现多态虚函数机制纯虚函数与抽象类 3 赋值兼容性规则 每一个派生类的对象 都是基类的一个对象 赋值兼容规则是指在公有派生情况下 一个公有派生类的对象可以当作基类的对象使用 反之则禁止 派生类的对象可以赋值给基类对象 派生类的对象可以初始化基类的引用 指向基类的指针也可以指向派生类 通过基类对象名 指针只能使用从基类继承的成员 4 派生类对象赋值给基类对象 Mammalm 3 5 Dogd 2 3 LAB m d 通过m不能访问或间接访问breed成员 5 基类对象赋值给派生类对象 Mammalm 2 3 Dogd 3 4 LAB d m X 6 派生类对象初始化基类引用 Dogd 2 3 LAB Mammal虽然rp是c的引用 但只能访问基类部分数据和方法 7 派生类对象地址赋值基类指针 Dogd 2 3 LAB Mammal pd 基类指针可指向派生类对象通过pd只能访问基类部分的数据和接口 8 Mammal基类 classMammal public Mammal age 1 cout Mammalconstructor n Mammal cout Mammaldestructor n voidspeak const cout Mammalspeak n voidmove const cout Mammal moveonestep n protected intage 9 Dog类 classDog publicMammal public Dog cout Dogconstructor n Dog cout Dogdestructor n voidwagTail cout Waggingtail n voidspeak const cout Woof n voidmove const cout Dogmoves5steps n Dog类中重写了speak和move方法 同时增加了wagTail方法 10 测试程序 intmain Mammal pDog newDog pDog move pDog speak deletepDog pDog NULL return0 在堆中创建Dog对象 使用Mammal类指针pDog指向它 因为pDog的类型为Mammal指针类型 会调用Mammal类的move和speak方法 编译时期进行的函数调用绑定 尽管pDog指向的是Dog对象 但只能调用基类方法 11 一种期望 voidspeak Mammal pAnimal pAnimal speak intmain Mammal pDog newDog speak pDog Mammal pCat newCat speak pCat deletepDog pDog NULL deletepCat pCat NULL return0 定义通用的处理函数speak 形参指向Mammal的指针 可以接收Dog或Cat对象地址希望能够调用实际传递对象的speak方法 统一处理不同的对象 由于编译期静态绑定 导致2次调用的都是基类的speak 12 引入多态 在基类中 将子类中都会存在并需要重写的方法声明为虚函数 virtual 就会引入多态的效果 定义基类的指针或引用 使其指向或引用基类或派生类的对象 调用虚函数时 系统将调用实际所指向对象的方法 使用基类指针或引用调用方法 不用关心实际所指向的对象 是一种运行时多态 编译器编译时未做绑定 而是在运行时根据实际对象临时决策 13 多态的变化 classMammal public Mammal age 1 cout Mammalconstructor n Mammal cout Mammaldestructor n virtualvoidspeak const cout Mammalspeak n voidmove const cout Mammal moveonestep n protected intage 通过virtual关键词将speak声明为虚函数 14 多态的变化 classDog publicMammal public Dog cout Dogconstructor n Dog cout Dogdestructor n voidwagTail cout Waggingtail n virtualvoidspeak const cout Woof n voidmove const cout Dogmoves5steps n 基类中的speak声明为virtual后 派生类中重写的方法自动成为虚函数 但明确指出是一种良好编程习惯 从Dog再派生子类时 看Dog头文件 可判断speak为虚函数 15 测试程序 intmain Mammal pDog newDog pDog move pDog speak deletepDog pDog NULL return0 在堆中创建Dog对象 使用Mammal类指针pDog指向它 由于将speak声明为虚函数 通过pDog调用speak时调用的将是Dog类的方法 而move方法没有声明为虚函数 通过pDog只能调用Mammal类的move方法 16 多态的要点 实现多态的3个基本条件基类中声明虚函数 子类中重写虚函数 函数签名与基类完全相同 定义基类指针或引用 通过指针或引用调用虚函数 17 本章内容安排 多态的概念虚函数实现多态虚函数机制纯虚函数与抽象类 18 完整示例 Mammal类 classMammal public Mammal age 1 Mammal virtualvoidspeak const cout Mammalspeak n protected intage 19 完整示例 子类 classDog publicMammal public virtualvoidspeak const cout Woof n classCat publicMammal public virtualvoidspeak const cout Meow n 派生类中重写基类的虚函数 并且函数签名完全一致 为多态做好准备 20 完整示例 子类 classHorse publicMammal public virtualvoidspeak const cout Whinny n classPig publicMammal public virtualvoidspeak const cout Oink n 21 测试程序 intmain Mammal array 5 Mammal ptr intchoice i array是一个指针数组 含有5个元素 每个元素是1个Mammal类型的指针 22 测试程序 intmain for i 0 i choice switch choice case1 ptr newDog break case2 ptr newCat break case3 ptr newHorse break case4 ptr newPig break default ptr newMammal break array i ptr 在堆中创建对象 使用基类指针指向所创建的对象 23 测试程序 includeintmain for i 0 ispeak deletearray i return0 array是一个指针数组 array i 是Mammal类型指针 通过其调用speak方法实现多态效果 不用关心指针实际指向的对象类型 只需要调用speak方法 系统多态性帮助我们调用正确的方法版本 24 本章内容安排 多态的概念虚函数实现多态虚函数机制纯虚函数与抽象类 25 对象的构建 无虚函数 创建派生类对象时 首先调用基类的构造函数 再调用派生类的构造函数 每个派生类对象有2个部分 基类部分由基类构造函数构建 派生类部分由派生类构造函数构建 26 对象的构建 含虚函数 类中声明虚函数后 多数编译器将为每个类建立虚函数表 v table 在每个对象中插入1个指针 指向对应的虚函数表 定义Mammal对象时 vptr指向该类的虚函数表 Mammal类的虚函数表 27 对象的构建 含虚函数 定义Dog类对象时 先构建Mammal部分 此时vptr指向基类的虚函数表 再构建Dog部分时 将vptr替换指向Dog类的虚函数表 Mammal类的虚函数表 Dog类的虚函数表 28 多态的要点 实现多态的3个基本条件基类中声明虚函数 子类中重写虚函数 函数签名与基类完全相同 定义基类指针或引用 通过指针或引用调用虚函数 基类中声明虚函数 子类中没有重写 不产生多态 直接调用基类中的方法 子类中扩展的方法 基类中没有定义 通过基类指针或引用禁止调用 语法错误 子类中声明虚函数 子类中重写但签名不同 不产生多态 直接调用的基类中的方法 按值传递对象时 不能实现多态 赋值时会产生切片效果 29 基类指针不能访问子类特有方法 如果Dog类中扩展了wagTail方法 但Mammal类中没有wagTail方法 通过基类指针不允许访问wagTail方法 Mammal pDog newDog pDog wagTail Dog pRealDog dynamic cast pDog if pRealDog pRealDog wagTail X 如果pDog确实指向1个Dog对象 可通过dynamic cast将其转换为Dog类型指针 从而可以调用wagTail方法 dynamic cast进行运行时类型检查 若转换失败 会返回空指针 但尽量避免这种强制转换 30 对象不能实现多态 voidvalueFunction MammalmammalValue mammalValue speak voidptrFunction Mammal pMammal pMammal speak voidrefFunction Mammal 通过指针或引用才能实现多态 传递对象不能实现多态 31 多态的补充说明 应该将析构函数声明为虚函数 如果希望所写的类被继承并多态执行 不声明虚析构函数情况下 基类指针指向堆中创建的子类对象 执行delete操作时 将会产生内存泄漏声明虚析构函数情况 执行delete时 由于多态效果 调用子类的析构函数 从而引起基类析构函数调用 构造函数不能声明为虚函数 使用虚函数实现多态增强了程序的灵活性 但由于维护虚函数表 会带来运行时的开销 32 本章内容安排 多态的概念虚函数实现多态虚函数机制纯虚函数与抽象类 33 Shape类 classShape public Shape virtual Shape virtualdoublegetArea return 1 virtualdoublegetPerim return 1 形状类是其它具体形状类型的基类 计算面积 周长和绘图功能对shape类实际上没有多大的意义 34 Circle类 constdoublePI 3 14 classCircle publicShape public Circle doublenewRadius radius newRadius virtual Circle virtualdoublegetArea returnPI radius radius virtualdoublegetPerim return2 PI radius private doubleradius Circle类重写了基类的2个虚函数 35 Rectangle类 classRectangle publicShape public Rectangle doublenewLen doublenewWidth length newLen width newWidth virtual Rectangle virtualdoublegetArea returnlength width virtualdoublegetPerim return2 length 2 width virtualdoublegetLength const returnlength virtualdoublegetWidth const returnwidth private doublewidth doublelength Rectangle类重写了基类的2个虚函数 36 将Shape声明为抽象数据类型 Shape是各种形状的基类 但定义Shape类对象并没有意义 Shape更应该作为一种抽象概念 将Shape类中的虚函数定义为纯虚函数 表明Shap
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 婴儿安全知识培训课件
- 年度安全再培训目的课件
- 工业消防安全培训教材课件
- 年底员工安全培训总结
- 威海电梯员安全培训课件
- 平舌与翘舌的课件
- 食品行业食品安全追溯体系在食品安全风险评估与控制中的应用创新案例研究重点报告
- 夜雨寄北课件
- 2025年农业绿色发展政策支持下的农业节能减排技术应用研究
- 新能源汽车车身结构创新与电池布局优化报告2025
- 子宫内膜异位症合并不孕的手术治疗
- 八个有趣模型搞定外接球内切球问题(学生版)
- 分期贷款利息计算表
- 两篇古典英文版成语故事塞翁失马
- 名著阅读《朝花夕拾 狗猫鼠》课件-部编版语文七年级上册
- 燃气轮机介绍课件
- 2022年国家公务员考试申论真题及答案解析(地市级)
- 名师成长的路径与修炼(教师版)课件
- 案外人执行异议之诉课件
- 西方经济学导论全套课件
- “基础教育精品课”PPT课件模板
评论
0/150
提交评论