当前位置: 首页 > news >正文

虚函数表的设计和多态的实现

虚表指针

类直接定义虚函数:编译器自动在对象头部插入 vptr。

继承含虚函数的父类:子类复用父类的 vptr,不会创建新的vptr

单继承(子类继承一个含虚函数的父类)

1.创建新的虚函数表

2.沿用父类的虚表指针(vptr)指向新虚表(vtable)

3.重写父类虚函数,覆盖虚表中原函数指针

4.新增虚函数,往虚表中加函数指针

5.vptr 通常位于对象的头 4/8 字节

class Base {
public:virtual void foo() {}  // vptr 指向 Base 的虚表int a;
};class Derived : public Base {
public:virtual void foo() override {}  // 重写,虚表更新virtual void bar() {}          // 新增虚函数,追加到虚表int b;
};[ vptr ]  --> 指向 Derived 的虚表(含 foo 和 bar)
[ a ]     // Base::a
[ b ]     // Derived::b

多继承(继承多个含虚函数的父类)

1.创建新的虚函数表,有几个父类就新建几个

2.沿用父类的虚表指针指向新虚表

3.重写父类虚函数,覆盖对应虚表中原函数指针

4.新增虚函数,往第一张虚表中加函数指针

class Base1 {
public:virtual void foo1() {}  // Base1 有 vptrint b1;
};class Base2 {
public:virtual void foo2() {}  // Base2 有 vptrint b2;
};class Derived : public Base1, public Base2 {
public:virtual void foo1() override {}  // 重写 Base1::foo1virtual void bar() {}           // 新增虚函数,追加到 Base1 的虚表int d;
};[ Base1::vptr ]  --> 指向 Derived 为 Base1 新建的虚表(含 foo1 和 bar)
[ Base1::b1 ]    // Base1 的成员
[ Base2::vptr ]  --> 指向 Derived 为 Base2 新建的虚表(仅含 foo2)
[ Base2::b2 ]    // Base2 的成员
[ Derived::d ]   // 子类新增成员

一些问题

1.虚函数表需要对象的指针才可以找到,所以静态成员函数,友元函数玩不了

2.析构函数设为虚函数,在delete父类指针时,通过去虚表中查找可以正确调用子类析构,避免内存泄漏

3.内联函数和虚函数是冲突的,内联函数会将函数的指令展开在程序中,而虚函数是通过虚表去查找调用

多态的实现

1.引用的底层是指针

  • 当用 父类引用/指针 指向子类对象时,本质上是 用父类类型的指针访问子类对象

2.父类指针会指向特定位置

  • 如果是 单继承,父类指针直接指向子类对象的起始地址(和子类指针相同)。

  • 如果是 多重继承,父类指针可能会 调整偏移量,指向子类对象中对应父类子对象的起始位置。

3.调用虚函数就是用父类指针取头4/8字节,得到虚表指针,去查虚表调用对应虚函数


http://www.mrgr.cn/news/100433.html

相关文章:

  • 关于Android Studio的AndroidManifest.xml的详解
  • pyspark将hive数据写入Excel文件中
  • 视觉/深度学习/机器学习相关面经总结(2)(持续更新)
  • 合理布局结构体,精打细算 cacheline
  • MCP实战派【1】-SSE
  • Arduino 入门学习笔记(六):外部中断实验
  • 基于知识库的智能客户服务工具
  • 辞九门回忆
  • 练习普通话,声音细柔和
  • 如何理解promise 续一
  • 解决Cline的Shell Integration Unavailable问题
  • OpenSSH配置连接远程服务器MS ODBC驱动与Navicat数据库管理
  • C++初阶-STL简介
  • 10 DPSK原始对话记录
  • ALTER TABLE 删除DROP表列的报错: 因为有一个或多个对象访问此列
  • MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - sleep
  • 基于云原生架构的后端微服务治理实战指南
  • 【Linux】Centos7 在 Docker 上安装 mysql8.0(最新详细教程)
  • 【C++ 类和数据抽象】消息处理示例(2)
  • SHCTF-REVERSE