C++虚函数详解:内存布局与实现机制
88 浏览量
更新于2024-08-31
收藏 360KB PDF 举报
本文将深入浅出地探讨C++中的虚函数机制,尤其针对VS2013生成的32位代码进行讲解。首先,我们回顾了一个示例,其中`CBase`类定义了两个虚函数`VFun1`和`VFun2`,以及一个数据成员`data`。当创建`CDerived`类的对象并将其赋值给`CBase`类型的指针`pBase`时,调用`VFun1`和`VFun2`产生了意外的输出结果,因为内存布局发生了变化。
在C++中,当一个类包含虚函数时,编译器会在每个对象的存储空间头部自动添加一个虚函数表(Virtual Function Table,简称VTable)。这个VTable是一个动态链接表,用于存储该类及其所有基类的所有虚函数的地址。每个VTable项代表一个虚函数,索引由虚函数在基类继承链上的位置决定,-1通常表示终止符或未定义。
在`CDerived`类继承自`CBase`后,`CBase`类的VTable会包含`VFun1`、`VFun2`和析构函数,而`CDerived`类自己的虚函数`VFunNew`、`VFun1`和析构函数也会被添加到VTable中。由于`CDerived`重写了`VFun1`,所以它的地址会取代`CBase`类中的`VFun1`位置。
当我们创建`CDerived`对象并将其赋值给`CBase`指针时,实际上`pBase`指向的是`CDerived`对象的地址,而不是`CBase`对象的地址。因此,`pBase->VFun1()`实际上是调用了`CDerived`类中的`VFun1`,而不是`CBase`的版本。这就是为何输出结果显示`VFun1`而不是`CBase::VFun1`的原因。
`CDerived`对象的内存布局包含了`CBase`的虚函数表指针,以及`data`成员,它们的相对位置由编译器决定,通常数据成员紧跟在基类的VTable之后,以保持对象的紧凑性。至于为什么`offsetof(CBase, data)`的结果是4,这是因为`data`位于VTable之后,而VTable占4字节,所以两者之间的偏移是4。
总结来说,C++的虚函数实现涉及动态链接表——虚函数表,它使得子类对象能够根据实际类型调用正确的函数,即便通过基类指针。理解内存布局对于调试和优化C++程序至关重要,尤其是处理多态行为时。通过这个实例,我们可以看到C++的运行时多态性和底层机制是如何协同工作的。
2020-08-25 上传
2016-09-10 上传
2020-12-25 上传
2021-01-20 上传
2021-01-01 上传
2020-12-25 上传
2020-09-02 上传
2021-01-20 上传
2020-08-18 上传
weixin_38639642
- 粉丝: 9
- 资源: 894
最新资源
- Raspberry Pi OpenCL驱动程序安装与QEMU仿真指南
- Apache RocketMQ Go客户端:全面支持与消息处理功能
- WStage平台:无线传感器网络阶段数据交互技术
- 基于Java SpringBoot和微信小程序的ssm智能仓储系统开发
- CorrectMe项目:自动更正与建议API的开发与应用
- IdeaBiz请求处理程序JAVA:自动化API调用与令牌管理
- 墨西哥面包店研讨会:介绍关键业绩指标(KPI)与评估标准
- 2014年Android音乐播放器源码学习分享
- CleverRecyclerView扩展库:滑动效果与特性增强
- 利用Python和SURF特征识别斑点猫图像
- Wurpr开源PHP MySQL包装器:安全易用且高效
- Scratch少儿编程:Kanon妹系闹钟音效素材包
- 食品分享社交应用的开发教程与功能介绍
- Cookies by lfj.io: 浏览数据智能管理与同步工具
- 掌握SSH框架与SpringMVC Hibernate集成教程
- C语言实现FFT算法及互相关性能优化指南