当前位置: 代码网 > it编程>编程语言>C/C++ > C++中虚函数表的初始化时机

C++中虚函数表的初始化时机

2026年07月24日 C/C++ 我要评论
虚函数表(vtable)的初始化时机虚函数表的初始化分为两个阶段,一个是编译/链接期,一个是运行期,二者分工不同:编译/链接期:vtable 结构的确定(静态阶段)编写包含虚函数的类(比如 class

虚函数表(vtable)的初始化时机

虚函数表的初始化分为两个阶段,一个是编译/链接期,一个是运行期,二者分工不同:

编译/链接期:vtable 结构的确定(静态阶段)

编写包含虚函数的类(比如 class a { virtual void f(); })并编译时:

  • 编译器会为每个包含虚函数的类(或继承了虚函数的子类)生成一份固定的 vtable 数据结构(本质是函数指针数组)。
  • 这个 vtable 会被编译到程序的只读数据段(.rodata)中,和代码段一样,是程序启动前就确定好的“静态数据”。
  • 此时 vtable 里已经填好了各个虚函数的地址(比如 a::f 的地址)。

运行期:vptr(虚函数表指针)的初始化(动态阶段)

每个包含虚函数的对象,都会有一个隐藏的 vptr 成员(指向所属类的 vtable),这个指针的初始化:

  • 对于普通对象vptr 在对象构造函数执行的最开始阶段完成初始化(早于构造函数的函数体执行)
    • 子类对象构造时,会先初始化父类的 vptr,再初始化子类自己的 vptr
  • 对于全局/静态对象vptr 在程序启动后的全局初始化阶段(main 函数执行前)完成。
  • 对于 new 创建的对象vptroperator new 分配内存后、构造函数执行前初始化。

验证代码(c++)

#include <iostream>
using namespace std;

class base {
public:
    base() {
        // 此时 vptr 已经指向 base 的 vtable,调用虚函数会走 base 版本
        func(); // 输出 "base::func"
    }
    virtual void func() { cout << "base::func" << endl; }
};

class derived : public base {
public:
    derived() {
        // 此时 vptr 已经切换到 derived 的 vtable
        func(); // 输出 "derived::func"
    }
    void func() override { cout << "derived::func" << endl; }
};

int main() {
    derived d; 
    // 构造过程:
    // 1. 初始化 base 部分 → vptr 指向 base::vtable → 调用 base::func
    // 2. 初始化 derived 部分 → vptr 切换到 derived::vtable → 调用 derived::func
    return 0;
}

输出结果

base::func
derived::func

vptr 在构造函数执行时已经完成初始化,且子类构造时会覆盖父类的 vptr

常见误区

  1. ❌ 错误:“每次创建对象都会生成新的 vtable”
    ✅ 正确:一个类只有一份 vtable(编译期确定),所有对象的 vptr 都指向这份 vtable。
  2. ❌ 错误:“vptr 在构造函数体执行后初始化”
    ✅ 正确:vptr 初始化在构造函数的“初始化列表阶段”(编译器自动插入),早于函数体执行。
  3. ❌ 错误:“虚函数表在运行时动态生成”
    ✅ 正确:vtable 本身是编译期生成的静态数据,运行时只初始化 vptr 指向它。

总结

  1. 虚函数表(vtable)本身:编译/链接期生成,存储在只读数据段,属于类的静态资源,全局唯一。
  2. 虚函数表指针(vptr):运行期初始化,普通对象在构造函数执行前完成,子类构造时会覆盖父类的 vptr
  3. 核心逻辑:vtable 是“静态模板”,vptr 是“动态指针”,二者结合实现多态。

到此这篇关于c++中虚函数表的初始化时机的文章就介绍到这了,更多相关c++虚函数表初始化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com