卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

    • C++构造函数有几种,分别什么作用?
    • 什么是构造函数和析构函数?构造函数和析构函数可以是虚函数吗?为什么?
    • C++的重载和重写,以及它们的区别和实现方式
    • C++怎么实现多态
    • C++中的虚函数和纯虚函数有什么区别?
    • 虚函数怎么实现的?
    • 虚函数表是什么
      • 简要回答
      • 详细回答
      • 代码详解
      • 知识拓展
    • 多重继承的优缺点及菱形继承问题
    • 如何禁止一个类被继承
    • 深拷贝和浅拷贝的区别?
    • this指针的原理
    • C++如何实现一个单例模式?
  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# 虚函数表是什么

# 简要回答

虚函数表(VTable)是C++实现运行时多态性的核心机制,它是一个存储类虚函数地址的指针数组。每个包含虚函数的类都有一个虚函数表,对象通过隐藏的vptr指针访问该表来实现动态绑定。

虚函数表就像是一张函数地址清单,当类里有虚函数时,编译器会自动创建这个表。

# 详细回答

虚函数表是C++实现动态多态的关键数据结构,具有以下特点:

每个包含虚函数的类都有一个虚函数表

表中按声明顺序存储该类所有虚函数的函数指针

派生类会继承基类的虚函数表,并重写覆盖的虚函数指针

每个对象实例包含一个隐藏的vptr指针指向其类的虚函数表

调用虚函数时通过vptr间接寻址,实现运行时多态

虚函数表在编译期构造,运行期使用,是实现"一个接口,多种实现"的核心机制。

# 代码详解

#include <iostream>

class Base {
public:
    virtual void func1() { std::cout << "Base::func1" << std::endl; }
    virtual void func2() { std::cout << "Base::func2" << std::endl; }
    void func3() { std::cout << "Base::func3" << std::endl; }
};

class Derived : public Base {
public:
    void func1() override { std::cout << "Derived::func1" << std::endl; }
    virtual void func4() { std::cout << "Derived::func4" << std::endl; }
};

int main() {
    Base b;
    Derived d;

    Base* pb = &d;
    pb->func1();  // 输出 Derived::func1 - 动态绑定
    pb->func2();  // 输出 Base::func2
    // pb->func4(); // 错误: Base没有func4成员

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

以上代码Base类的虚函数表包含两个条目:&Base::func1和&Base::func2,其中func3不是虚函数

Derived类的虚函数表:

它会继承Base的虚函数表,覆盖func1为&Derived::func1

添加新条目&Derived::func4

func3是非虚函数,不进入虚函数表

通过基类指针调用虚函数时,通过对象的vptr找到Derived的虚函数表,再调用对应的函数

# 知识拓展

  • 知识图解 image

  • 面试官可能追问

虚函数表在内存中的什么位置?

答:通常位于程序的只读数据段(.rodata),由编译器在编译期生成

构造函数中能调用虚函数吗?会发生什么?

可以调用,但会静态绑定到当前类的实现,因为派生类构造时vptr还未指向派生类的虚函数表

虚函数与模板多态的区别?

虚函数是运行时多态,模板是编译时多态;虚函数有运行时开销但更灵活

Last Updated: 3/10/2026, 6:08:48 PM

← 虚函数怎么实现的? 多重继承的优缺点及菱形继承问题 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪