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

C++动态多态原理分析

class Animal
{
public:void speak() {cout << "Animal.speak()" << endl;}
};class Cat :public Animal 
{void speak() {cout << "Cat.speak()" << endl;}
};
void doWork(Animal& animal) {animal.speak();
}void test01()
{Animal an;doWork(an);Cat cat;doWork(cat);
}

  doWork函数使用Animal类来接收子类执行speak(),理想状态下应该是接收什么类,就执行什么类的speak(多态),而实际情况是无论接收哪个子类的对象,都只会执行Animal.doWork(),原因是代码在编译阶段就完成了地址绑定(地址早绑定),Animal animal = cat就决定了animal.speak()是Animal类的speak而不是cat类的speak,而要实现理想效果就需要代码在运行阶段完成地址绑定(地址晚绑定)。解决办法是将父类的speak函数变为虚函数。

virtual void speak() {cout << "Animal.speak()" << endl;
}

在这一步后,Animal类中会多出一个名为vfptr的指针,意为虚函数表指针,其指向一个虚函数表,虚函数表内保存着虚函数的信息,借助cl工具可以查看表结构如下:

image

 而Cat类在继承Animal类后,与父类一样,同样也会有一个vfptr的指针,同样指向一个虚函数表,虚函数表内保存着父类虚函数的信息。(未对父类虚函数重写)

image

 而在子类重写父类的虚函数后,会在子类的vftable会将父类的虚函数覆盖,而父类的虚函数表不变。

image

 而此时doWork(cat)输出的就是Cat.speak()了

http://www.zskr.cn/news/23853.html

相关文章:

  • Java基础——初识Math类,基本运算符,自增自减运算符,逻辑运算符,位运算符,三元运算符
  • ENC28J60
  • 第九章-实战篇-运维杰克
  • 硬件基础知识
  • Channel小结
  • bridge 一般是 网络桥接模块。
  • abc428
  • 华为hcip总纲
  • haiku
  • Asp.Net Core 解决使用 Docker调试时出现“准备容器时发生了一个非关键性错误。项目将继续正常工作。错误为: 路径中具有非法字符。”
  • [Linux] NeoVim安装和Lazyvim配置
  • ABC 随笔
  • 大数据分析基础及应用案例:第三周学习报告 ——Matplotlib 学习报告
  • 2025.10 训练日志
  • 矩阵的秩和逆
  • 全球AI推理扩展技术解析
  • 乱七八糟的知识点
  • 自监督学习在医疗AI中的技术搭建路径分析(下)
  • 2025/10/18
  • 模板机制作
  • 小马智行 VS 文远知行
  • nas webdav 挂载盘Git报错:fatal: detected dubious ownership in repository at - 何苦
  • 题解:P14254 分割(divide)
  • 【汇编和指令集 . 第2025 .10期】万般皆为投影
  • 小作业 12
  • 机器学习在视频质量检测中的技术应用
  • React Query入门指南:简化React应用中的信息获取
  • CSP-S模拟34/2025多校冲刺CSP模拟赛6
  • Java学习通互评5
  • 随机数技术