空派生类B场景下,C++会创建多少个虚函数表(vtable)?
C++派生类未重写虚函数时的虚表机制解析
先看你的测试代码:
#include <bits/stdc++.h> using namespace std; class A{ public: virtual void display(){ cout<<"A Class"<<endl; } }; class B: public A{ public: }; int main() { A *ob = new B(); ob->display();//A Class return 0; }
针对你的疑问的核心解释
1. 虚表(vtable)的生成情况
- 基类
A因为包含虚函数display,编译器会为它生成一个虚表,表内存储A::display的函数地址。 - 派生类
B虽然没有重写任何虚函数,但它继承了A的所有虚函数。编译器要么为B生成一个独立的虚表(表内display条目指向A::display),要么在优化场景下复用A的虚表——但无论哪种实现,B的虚表绝对不会是空的,它会包含所有继承自基类且未被重写的虚函数地址。你之前认为B的vtable为空的想法是错误的。
2. 多态调用的实际流程
- 当创建
B对象时,对象内部的虚指针(vptr)会指向B对应的虚表(或复用的A的虚表)。 - 执行
ob->display()时,程序会:- 通过
ob读取目标对象的虚指针,找到对应的虚表。 - 在虚表中取出
display对应的函数地址(这里就是A::display的地址)。 - 调用该函数,最终输出"A Class"。
- 通过
3. 误区纠正
完全不存在“调用时去父类vtable查找”的过程。派生类的虚表已经预先包含了继承来的虚函数地址,程序直接从当前对象的虚表中获取函数地址并调用,这是C++多态的核心逻辑——每个类的虚表存储了该类所有虚函数(含继承未重写的)的入口,对象的虚指针直接关联到自身类的虚表。
内容的提问来源于stack exchange,提问作者Fedrick
相关产品推荐
相关产品推荐

