首页 关于我们 成功案例 网络营销 电商设计 新闻中心 联系方式
QQ联系
电话联系
手机联系
QQ联系
电话联系
手机联系

c++中的vptr是什么 c++虚函数指针详解【底层】

发布时间:2026-01-02 00:00
发布者:冰火之心
浏览次数:
vptr 是 C++ 编译器为含虚函数的对象自动插入的隐藏指针,位于对象内存布局起始处,大小与平台指针宽度一致(32 位为 4 字节,64 位为 8 字节),指向所属类的虚函数表(vtable);它在构造函数执行前由编译器初始化,单继承下每个对象一个且恒在开头,多重继承时可能有多个。

vptr 是 C++ 编译器为每个含有虚函数的对象自动插入的一个隐藏指针,全称是 virtual function table pointer(虚函数表指针)。它不显式出现在类定义中,但真实存在于对象内存布局的最前端,指向该对象所属类的虚函数表(vtable)。

vptr 的位置和大小

在绝大多数主流编译器(如 MSVC、GCC、Clang)中:

  • vptr 位于对象内存布局的起始地址处(即对象首字节),紧随其后才是成员变量;
  • 其大小与平台指针宽度一致:32 位系统为 4 字节,64 位系统为 8 字节;
  • 可通过 sizeof 验证——例如一个仅含一个 int 和一个虚函数的类,在 64 位 Linux 下对象大小通常为 16 字节(8 字节 vptr + 4 字节 int + 4 字节对齐填充)。

vptr 怎么工作

当通过基类指针或引用调用虚函数时,实际执行流程依赖 vptr:

  • 从对象首地址读取 vptr 值(即取出虚函数表起始地址);
  • 根据被调用虚函数在类中声明的顺序,计算其在 vtable 中的索引(如第一个虚函数偏移为 0,第二个为 1);
  • 用该索引访问 vtable 对应位置的函数指针;
  • 间接跳转(call [rax] 类汇编指令)执行目标函数。

这个过程完全在运行时完成,与变量声明类型无关,只取决于对象实际类型。

vptr 不是“每个类一个”,而是“每个对象一个”

注意区分两个概念:

  • vtable 是类级别的:每个含虚函数的类有且仅有一个 vtable(存储在只读数据段 .rodata),所有该类对象共享同一张表;
  • vptr 是对象级别的:每个对象实例都拥有自己的 vptr 成员,它指向所属类的 vtable —— 派生类对象的 vptr 指向派生类的 vtable,而非基类的。

多重继承时可能有多个 vptr(如虚继承或菱形继承场景),但单继承下始终只有一个,且恒在对象开头。

vptr 的初始化时机

vptr 在对象构造过程中由编译器自动设置:

  • 进入构造函数体前,编译器先将当前类的 vtable 地址写入对象首部;
  • 若为派生类,构造顺序是:基类构造 → 成员初始化 → 派生类构造体;每一步都会更新 vptr 指向对应阶段的 vtable;
  • 因此在基类构造函数中调用虚函数,即使派生类已重写,也只会调用基类版本(此时派生类部分尚未构造,vptr 还指向基类 vtable)。


# function  # 只有一个  # 第二个  # 只会  # 出现在  # 才是  # 第一个  # 自己的  # 能有  # 多个  # 派生类  # table  # 对象  # linux  # pointer  # 多重继承  # 虚函数  # 继承  # 指针  # int  # 引用调用  # 构造函数  # 成员变量  # c++  # 字节  # 前端 


相关文章: 如何使用Golang mock对象进行单元测试_模拟依赖接口行为  c++怎么使用std::variant多态容器_c++ 17类型安全联合体访问【方法】  光遇办公室圣诞节物品在哪兑换-光遇办公室圣诞节物品兑换方法  html5如何实现懒加载图片_ intersectionobserver api用法【教程】  Win11如何设置环境变量 Win11添加和修改系统与用户变量【教程】  c++如何开发2d游戏_c++ SFML库图形渲染与碰撞检测【案例】  LINUX怎么查看进程_LINUX ps命令查看运行服务  Composer的--profile选项如何分析命令执行性能?(调试工具)  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  如何在 Go 中将测试文件放置于子目录中以优化项目结构  如何在 Go 项目中将测试文件组织到子目录中  c++如何使用spdlog日志库_c++高性能异步日志框架【教程】  如何在Golang中动态调用接口方法_Golang reflect调用接口函数示例  电脑浏览器广告弹窗太多怎么办_浏览器安装广告拦截插件教程【超详细】  国产GPU硬刚RTX 4060!砺算科技6nm芯片正式交付  整理分享:AO3可访问地址大全 实时更新的镜像入口  Python配置文件加载_多环境适配解析【教程】  Python文件操作最佳实践_稳定性说明【指导】  VSCode的Better Comments:让你的注释五彩斑斓  javascript函数式编程是什么_纯函数与副作用如何理解?  《星露谷物语》作者向C#框架捐12.5万美元!承诺每月资助  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  如何为不同团队 ID 动态生成多个非值班状态按钮  智谱AI营销文案生成怎么用_智谱AI营销文案生成使用方法详细指南【教程】  海棠搜书官网入口直接进 海棠文化在线阅读官方网站入口  项圈+腿环 这就是魅魔!《绝区零》超大胆时装免费  ChatGPT官方入口 ChatGPT官网网页版访问步骤详解  如何在嵌套树形结构中递归查找指定 slug 的节点及其完整子树  学习通网页版官方入口_超星平台在线课程学习中心  Java实现学生信息管理系统_从数据结构到功能模块完整实战 


相关栏目: 【 行业资讯17850 】 【 软件资源51899 】 【 网站技术89748 】 【 百度推广44206 】 【 网络营销84187 】 【 运营推广93002 】 【 AI优化91086 】 【 网络优化117696 】 【 网址导航107142