【C++】 继承与多态(下)


多态(知识点下)

1. 实现方式

从底层的⻆度Func函数中ptr->BuyTicket(),是如何作为ptr指向Person对象调 Person::BuyTicket, ptr指向Student对象调⽤Student::BuyTicket的呢?通过下图我们可以看到,满⾜多态条件后,底层不再是编译时通过调⽤对象确定函数的地址,⽽是运⾏时到指向的对象的虚表中确定对应的虚函数的地址,这样就实现了指针或引⽤指向基类就调⽤基类的虚函数,指向派⽣类就调⽤派⽣类对应的虚函数。第⼀张图,ptr指向的Person对象,调⽤的是Person的虚函数;第⼆张图,ptr指向的Student对象,调⽤的是Student的虚函数。


2.动态绑定与静态绑定

• 对不满⾜多态条件(指针或者引⽤+调⽤虚函数)的函数调⽤是在编译时绑定,也就是编译时确定调⽤ 函数的地址,叫做静态绑定。
• 满⾜多态条件的函数调⽤是在运⾏时绑定,也就是在运⾏时到指向对象的虚函数表中找到调⽤函数 的地址,也就做动态绑定。

cpp 复制代码
// ptr是指针+BuyTicket是虚函数满⾜多态条件。
// 这⾥就是动态绑定,编译在运⾏时到ptr指向对象的虚函数表中确定调⽤函数地址
ptr->BuyTicket();
00EF2001 mov eax,dword ptr [ptr]
00EF2004 mov edx,dword ptr [eax]
00EF2006 mov esi,esp
00EF2008 mov ecx,dword ptr [ptr]
00EF200B mov eax,dword ptr [edx]
00EF200D call eax
// BuyTicket不是虚函数,不满⾜多态条件。
// 这⾥就是静态绑定,编译器直接确定调⽤函数地址
ptr->BuyTicket();
00EA2C91 mov ecx,dword ptr [ptr]
00EA2C94 call Student::Student (0EA153Ch)

3. 虚函数表

一、虚函数表基本特性

  1. 虚表内容:存储类所有虚函数的地址。
  2. 共享规则:同类型对象共用同一张虚表;不同类型对象拥有独立虚表(基类、派生类各有自己的虚表)。
  3. 本质:虚表是一个存储虚函数指针的函数指针数组。
  4. 结束标记:VS 编译器会在数组末尾存放0x00000000作为结束标记; g++ 无此标记(C++ 标准未规定,由编译器实现)。

二、派生类与虚表、虚指针

  1. 派生类构成:分为两部分 → 继承的基类部分 + 自身新增成员。
  2. 虚指针规则
    • 基类部分自带虚函数表指针(vptr);
    • 派生类不会额外生成新的虚指针;
    • 派生类中基类部分的虚指针 ≠ 基类对象的虚指针(二者相互独立)。
  3. 虚表覆盖规则
    • 派生类重写(override)基类虚函数时:派生类虚表中对应位置的函数地址会被覆盖为派生类自己的函数地址。
  4. 派生类虚表完整内容

① 未被重写的基类虚函数地址

②****被重写的基类虚函数 → 替换为派生类重写后的地址

③****派生类新增的虚函数地址

5.虚函数表存储地址

继承与多态复习汇总

派生类的析构函数往往还需要连同父类析构函数一起调用,同时清除父类的资源

维度 继承(is-a) 包含(has-a)
核心含义 逻辑上的 "父子关系",子类复用基类的定义 物理上的 "内存存在",对象里实实在在有这块数据
针对对象 针对类,描述类之间的关系 针对对象,描述对象的内存布局
基类非静态成员变量 子类继承了这些成员(但私有成员不能直接访问) 派生类对象一定包含这些成员变量(会生成基类子对象,占内存)
基类静态成员变量 子类会继承对它的访问权限(比如公有静态成员子类也能访问) 派生类对象不包含它(静态成员属于类,不属于任何对象)
基类私有成员 子类继承了,但不能直接访问 派生类对象包含它(内存里有,只是你不能直接用)

相关推荐
EXI-小洲4 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员5 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导5 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan5 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
小灰灰搞电子5 小时前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
QT界面美化性能优化5 小时前
QT+AI:使用AI技术为QT应用程序赋能
c++·人工智能·qt·opencv·qt教程·qt6.3
m0_695251495 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
大衛說6 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
学习星球7 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
可乐鸡翅yeah_7 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线