MST

星途 面试题库

面试题:C++ 虚函数与对象内存结构

已知类层次结构为:class Base { virtual void virtualFunc() {} }; class Derived : public Base { void virtualFunc() override {} }; 详细阐述Base类对象和Derived类对象在内存中的表现,尤其是虚函数表指针(vptr)在其中的作用与存储位置,以及在多态调用时,对象内存结构如何影响函数的正确调用。
31.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. Base类对象内存表现
    • 内存布局:当创建一个Base类对象时,其内存中至少包含为类中数据成员分配的空间(在本题Base类中无数据成员,暂不考虑数据成员内存)。同时,由于Base类含有虚函数virtualFunc,它会有一个虚函数表指针(vptr)。
    • 虚函数表指针(vptrvptr指向一个虚函数表(vtable)。虚函数表是一个数组,数组中的每个元素是一个函数指针,指向对应的虚函数。在Base类的虚函数表中,virtualFunc的函数指针指向Base::virtualFunc函数的实现。vptr的存储位置通常在对象内存布局的开始位置(不同编译器可能有差异,但大多数现代编译器是这样)。
  2. Derived类对象内存表现
    • 内存布局Derived类对象在内存中首先包含Base类子对象部分,这部分和Base类对象内存布局类似,有vptr以及可能存在的Base类数据成员(本题无)。接着是Derived类新增的数据成员(如果有,本题无)。
    • 虚函数表指针(vptrDerived类对象同样有一个vptr,它也指向一个虚函数表。由于Derived类继承自Base类并覆盖了virtualFuncDerived类的虚函数表和Base类虚函数表结构相似,但对于被覆盖的virtualFunc,其虚函数表中的函数指针指向Derived::virtualFunc函数的实现。vptrDerived类对象中的存储位置也通常在对象内存布局开始位置(包含Base类子对象部分的开始位置)。
  3. 多态调用时对象内存结构的影响
    • 多态原理:在多态调用中,如Base* ptr = new Derived(); ptr->virtualFunc();。首先,通过ptr指针找到Derived类对象内存起始位置,从而获取vptrvptr指向Derived类的虚函数表。
    • 函数调用:从虚函数表中根据virtualFunc在表中的索引找到对应的函数指针,该指针指向Derived::virtualFunc,于是调用的是Derived类中覆盖后的virtualFunc函数实现。这种机制使得通过基类指针或引用调用虚函数时,能够根据对象的实际类型(运行时类型)来调用正确的函数,实现多态行为。内存结构中vptr和虚函数表的存在是实现多态的关键,它们在运行时动态确定要调用的函数,而非在编译时根据指针类型静态确定。