MST

星途 面试题库

面试题:C++空类内存布局与编译器优化及多态特性的关联

考虑一个包含虚函数的空类`class VirtualEmpty { virtual void func() {} };`,结合编译器优化机制,阐述该空类的`sizeof`值与内存布局情况。如果存在多个继承自`VirtualEmpty`的子类,在运行时多态场景下,内存布局会如何进一步变化,对程序的性能和内存管理产生哪些影响。
19.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. VirtualEmpty类的sizeof值与内存布局

    • sizeof:在大多数编译器实现下,sizeof(VirtualEmpty)通常为一个指针的大小(例如在64位系统上为8字节)。这是因为虽然类本身没有数据成员,但由于存在虚函数,编译器会为该类生成一个虚函数表指针(vptr),用于实现运行时多态。
    • 内存布局:对象的内存布局中,最开始的位置存放虚函数表指针(vptr)。虚函数表(vtable)是一个存储类虚函数地址的表,每个包含虚函数的类都有一个对应的虚函数表。当对象调用虚函数时,通过vptr找到对应的虚函数表,进而找到实际要调用的函数地址。
  2. 多个继承自VirtualEmpty的子类在运行时多态场景下的内存布局变化

    • 内存布局变化:每个子类对象同样在开头位置存放指向其自身虚函数表的指针(vptr)。如果子类重写了父类的虚函数,那么虚函数表中对应函数的地址会被替换为子类重写后的函数地址。如果子类定义了新的虚函数,虚函数表会增加新的条目。
    • 对程序性能的影响
      • 优点:运行时多态使得程序具有更好的灵活性和可扩展性。在需要根据对象实际类型来决定调用哪个函数的场景下,运行时多态提供了一种优雅的解决方案。例如在图形绘制系统中,不同形状(如圆形、矩形)继承自一个基类,通过运行时多态可以根据实际对象类型调用相应的绘制函数。
      • 缺点:由于需要通过vptr和虚函数表来间接调用函数,相比直接函数调用会引入一定的性能开销。每次虚函数调用都需要额外的指针解引用操作,这在频繁调用虚函数的场景下可能会影响性能。
    • 对内存管理的影响
      • 优点:内存管理相对清晰,每个对象的虚函数表指针和虚函数表的内存管理由编译器和运行时库自动处理,开发者只需要关注对象本身的创建和销毁。
      • 缺点:由于每个对象都需要一个虚函数表指针,会增加对象的内存占用。并且虚函数表本身也会占用额外的内存空间,当存在大量包含虚函数的对象时,内存开销会比较显著。