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

相关推荐
见过夏天5 小时前
C++ 基础入门完全指南
c++
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境3 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境3 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴4 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境6 天前
C++ 的Eigen 库全解析
c++
卷无止境6 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴6 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
博客18007 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝