MST

星途 面试题库

面试题:C++ 空类 sizeof 值与编译器优化及多重继承

在 C++ 中,考虑多重继承场景,如 `class A {}; class B {}; class C : public A, public B {};`。从编译器优化角度出发,分析 `sizeof(C)` 的取值情况以及编译器如何在保证空类非零 sizeof 值的基础上,处理多重继承时的内存布局以提高空间利用率和访问效率。如果其中一个基类为空类,另一个基类有成员变量,这又会对 `sizeof(C)` 产生怎样的影响,详细说明编译器在这种情况下的处理机制。
40.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. sizeof(C) 取值情况分析
    • 在C++中,空类的 sizeof 值不为0,通常为1字节,这是为了保证每个对象都有唯一的地址。对于 class C : public A, public B {};,如果 AB 都是空类,sizeof(C) 通常至少为1字节。因为编译器会为 C 的实例分配至少1字节的空间,以满足对象有唯一地址的要求。
    • 从空间利用率角度,编译器不会为每个空基类单独分配空间,而是将 C 作为一个整体,只分配满足最小要求的空间。
    • 从访问效率角度,由于空类没有成员变量,对空基类的访问(例如通过 C 的实例访问 AB 的成员,虽然这里没有成员)通常不涉及复杂的内存偏移计算,效率较高。
  2. 多重继承时内存布局及优化
    • 编译器在处理多重继承的内存布局时,会按照继承列表的顺序排列基类子对象。即 C 的内存布局中,先存放 A 子对象,再存放 B 子对象。这样的布局使得通过 C 的实例访问 AB 的成员(如果有的话)时,偏移量计算相对简单,提高了访问效率。
    • 在保证空类非零 sizeof 值的基础上,编译器通过共享空间等方式提高空间利用率。例如对于多个空基类,不会为每个空基类都分配1字节,而是整体只分配满足最小要求的空间。
  3. 一个基类为空类,另一个基类有成员变量的情况
    • 假设 class A {}; 为空类,class B { int x; }; 有成员变量,class C : public A, public B {};。此时 sizeof(C) 的值等于 sizeof(B)(通常为4字节,假设 int 为4字节)。
    • 编译器处理机制如下:
      • 内存布局上,先排列空基类 A,但由于 A 为空类,不占用额外空间。然后排列有成员变量的 B 子对象。所以 C 的实例内存布局和 B 的实例类似,只是逻辑上包含了 A 子对象。
      • 对于访问效率,通过 C 访问 B 的成员变量 x 时,偏移量计算基于 BC 中的位置,相对简单直接。而访问 A(虽然无成员)同样不涉及复杂偏移计算,因为其不占空间。这样既保证了空间利用率(空基类不额外占空间),又维持了较好的访问效率。