虚继承与空基类优化

参考文章 虚继承与空基类优化

class TEST_X {};									// 1

class TEST_Y : public virtual TEST_X {				// 12 
	virtual void fun() {}; // 虚表4 //指虚基类的表指针4
	char c; };	// 字节对齐 4  // 空基类优化为0

class TEST_Z : public TEST_X {						// 8
	virtual void fun() {};  // 空基类优化为 0
	char c; };				// 字节对齐4 // 虚函数表4

class TEST_A : public TEST_Y, public TEST_Z {};		// 24

int main() {
	cout << sizeof(TEST_X) << " " << sizeof(TEST_Y) << " "
		<< sizeof(TEST_Z) << " " << sizeof(TEST_A) << endl;
	return 0;
}

在vs的开发人员工具上使用 cl -d1reportSingleClassLayoutTEST_X 源.cpp 命令,查看各类的内存布局情况。

  • C++标准规定,空类必须拥有非零的大小以保持对象的本质,使得这一class在实例化对象时得以在内存中配置独一无二的地址。
class TEST_X    size(1):
        +---
        +---
  • microsoft编译器引入所谓的virtual base class table。如果一个class有一个或多个virtual base classes,就会由编译器安插一个指针,指向virtual base class table。真正的virtual base class的指针就放在这个table中;
class TEST_Y    size(12):
        +---
 0      | {vfptr}
 4      | {vbptr}
 8      | c
        | <alignment member> (size=3)
        +---
        +--- (virtual base TEST_X)
        +---

TEST_Y::$vftable@:
        | &TEST_Y_meta
        |  0
 0      | &TEST_Y::fun

TEST_Y::$vbtable@:
 0      | -4
 1      | 8 (TEST_Yd(TEST_Y+4)TEST_X)

TEST_Y::fun this adjustor: 0
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
          TEST_X      12       4       4 0
  • 在TEST_Z中我们是普通的public继承,因此并没有产生{vbptr}指针。因此在该类中仅存在一个指向虚表的{vfptr}指针和内存对齐后占4字节的变量c
class TEST_Z    size(8):
        +---
 0      | {vfptr}
 4      | +--- (base class TEST_X)
        | +---
 4      | c
        | <alignment member> (size=3)
        +---

TEST_Z::$vftable@:
        | &TEST_Z_meta
        |  0
 0      | &TEST_Z::fun

TEST_Z::fun this adjustor: 0
  • 类TEST_A继承了两个类
class TEST_A    size(24):
        +---
 0      | +--- (base class TEST_Y)
 0      | | {vfptr}
 4      | | {vbptr}
 8      | | c
        | | <alignment member> (size=3)
        | +---
16      | +--- (base class TEST_Z)
16      | | {vfptr}
20      | | +--- (base class TEST_X)
        | | +---
20      | | c
        | | <alignment member> (size=3)
        | +---
        +---
        +--- (virtual base TEST_X)
        +---

TEST_A::$vftable@TEST_Y@:
        | &TEST_A_meta
        |  0
 0      | &TEST_Y::fun

TEST_A::$vftable@TEST_Z@:
        | -16
 0      | &TEST_Z::fun

TEST_A::$vbtable@:
 0      | -4
 1      | 20 (TEST_Ad(TEST_Y+4)TEST_X)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
          TEST_X      24       4       4 0

有关空基类优化 http://www.cantrip.org/emptyopt.html
在这里插入图片描述

  struct Bar { };
  struct Foo {
    struct Bar a[2];
    struct Bar b;
  };
  Foo f;

-------------------------------------------------------
  struct Baz
  +-----------------------------------+
  | +-------+-------+-------+-------+ |
  | | Bar b | XXXXX | XXXXX | XXXXX | |
  | +-------+-------+-------+-------+ |
  | +-------------------------------+ |
  | | int* p                        | |
  | +-------------------------------+ |
  +-----------------------------------+

空类类型的基础类子对象可能为零大小。(空基类优化,基类为空类时,优化为0字节

  struct Baz {
    Bar b;
    int* p;
  };
  -----------------------------------------------------
  struct Baz2
  +-----------------------------------+
  | +-------------------------------+ |
  | | int* p                        | |
  | +-------------------------------+ |
  +-----------------------------------+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫RT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值