CTTCG 21 Templates and Inheritance
零开销继承:空基类优化(EBCO)
The Empty Base Class Optimization (EBCO)
C++ 没有真正零大小的类,因为在数组等场景需要用地址区分元素。一般编译器上空类的大小是 1 个字节。不过,当基类为空时,EBCO 会使得基类在子类中不占空间。但是 EBCO 的适用有条件。下面的场景是从实践中观察出来的,可能并没有被标准定义,但它演示了 EBCO 失效:
- 定义“空基类组”的概念:如果空类型 B 继承了空类型 A,那么 B 和 A 可以存在于同一个空基类组(看成并查集会比较好理解)。和其他空类型不相关的类型可以认为自为一组。
- 某类型 C 继承了一个大小为 N 的空基类组,那么它至少具有 N 个字节。如果这个类型 C 不是空类型,则还有对齐要求。
- 继承多个空基类组,对子类对象所占用空间的要求等效于继承于最大的那个空基类组。
struct E1 {};
struct E2 : E1 {};
struct E20 {};
struct E21 : E20 {};
struct E22 : E20 {};
struct E23 : E20 {};
struct E24 : E20 {};
struct B : E1, E2, E20, E21, E22 {
// int a;
};
int main() {
std::cout << "sizeof(d): " << sizeof(B) << '\n';
// 输出为 3
// 如果 B 中还有个整形元素 a,输出为 4
// 如果 B 中还有个整形元素 a,并再继承空类 E23 和 E24,输出为 8(5对齐到4的倍数)
}
空成员优化
如果类中有一个空类的对象,那么它将无法适用 EBCO。将其改造为继承可以节约空间。