You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基类与派生类是否共享同一张虚表?求职面试存疑求助

基类与派生类的虚表是否共享?

结论:基类和派生类拥有各自独立的虚表,绝对不会共享。

核心原因

  • 虚表是类级别的专属数据结构:只要一个类包含虚函数(包括继承来的),编译器就会为它生成一张独立的虚表。基类的虚表属于基类,派生类的虚表属于派生类,二者在内存中是不同的区块。
  • 虚表指针的差异直接证明这点:基类对象的虚表指针指向基类虚表,派生类对象的虚表指针指向派生类虚表——你观察到的指针值不同,正是两个虚表独立的直接证据。
  • 派生类虚表的构成:它会继承基类虚函数的条目(如果派生类重写了该函数,条目指向派生类的实现;没重写则指向基类实现),同时新增派生类自己的虚函数条目,但整个表的内存地址和基类虚表完全分开。

面试官可能的误区

很多面试官混淆了两个概念:

  • 混淆了「虚表中共享函数实现地址」和「共享虚表本身」:比如派生类没重写基类虚函数时,虚表条目确实指向基类的函数代码,但这只是函数实现的复用,虚表本身还是派生类独立的。
  • 误把某些极端优化场景当普遍情况:极少数编译器可能在完全无重写、无新增虚函数的派生类上做合并虚表的优化,但这属于非标准的编译器扩展,不符合C++语言规范的要求,不能作为通用结论。

代码验证(C++)

#include <iostream>
using namespace std;

class Base {
public:
    virtual void func() { cout << "Base::func" << endl; }
};

class Derived : public Base {
public:
    void func() override { cout << "Derived::func" << endl; }
};

int main() {
    Base b;
    Derived d;
    // 提取虚表指针(仅用于演示,属于编译器实现细节)
    void** vptr_base = *(void***)(&b);
    void** vptr_derived = *(void***)(&d);
    
    cout << "基类虚表指针地址: " << vptr_base << endl;
    cout << "派生类虚表指针地址: " << vptr_derived << endl;
    return 0;
}

运行后会输出两个不同的地址,明确证明两个虚表是独立的。

内容的提问来源于stack exchange,提问作者user22481460

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:49:50