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 】





成员初始化 → 派生类构造体;每一步都会更新 vptr 指向对应阶段的 vtable;
