C++中虚继承类的sizeof大小

参考文献:《深度探索C++对象模型》

运行平台:Visual Studio 2015

最近在研读大佬Lippman的《深度探索C++对象模型》,对其中的虚继承类的sizeof大小产生了兴趣,因此编码测试了一下。

1. 基类为空

废话不说,先上源码:

# include <iostream>

using namespace std;

class X
{ 
};

class Y :virtual public X
{
};

class Z :virtual public X
{
};

class A :public Y, public Z
{
};

int main(void)
{
	cout << "X size: " << sizeof(X) << endl;
	cout << "Y size: " << sizeof(Y) << endl;
	cout << "Z size: " << sizeof(Z) << endl;
	cout << "A size: " << sizeof(A) << endl;

	return 0;
}

源码比较简单(弱智),类之间的关系如下:

1.1 win32平台

运行结果如下:

原因:

(1)class X有一个隐藏的1 byte的大小,是一个被编译器安插的char,这使得class X的两个objects得以在内存中配置独一无二的地址;

(2)class Y 和 class Z内部存在一个虚基类指针,指向各自的virtual base class X subobject,32位机器中指针为4 bytes,另外,编译器对empty virtual base class做了优化,节省了class X中的1byte;

(3)class A内部分别继承了的class Y 和 class Z的虚基类指针,大小就是4 + 4 = 8;

1.2 win64平台

运行结果如下:

(1)class X: 原因同win32;

(2)class Y 和 class Z内部的虚基类指针在64位机器上为8 bytes;

(3)class A的大小就是8 + 8 = 16;

2. 基类不为空

源码如下:

# include <iostream>

using namespace std;

class X
{ 
protected:
	int m_i;
};

class Y :virtual public X
{
};

class Z :virtual public X
{
};

class A :public Y, public Z
{
};

int main(void)
{
	cout << "X size: " << sizeof(X) << endl;
	cout << "Y size: " << sizeof(Y) << endl;
	cout << "Z size: " << sizeof(Z) << endl;
	cout << "A size: " << sizeof(A) << endl;

	return 0;
}

依旧是睿智(弱智)的源码,只是在class X中添加了一个int成员,类之间的关系如下:

2.1 win32平台

运行结果如下:

原因:

(1)class X有一个int成员,大小为4 bytes;

(2)class Y 和 class Z内部首先存在一个继承而来的int(不分是否为virtual继承),其次存在一个虚基类指针,指向各自的virtual base class X subobject,32位机器中指针为4 bytes,所以,它们的大小就是4 + 4 = 8;

(3)class A的大小比较有意思,sizeof(A) = sizeof(X) + (sizeof(Y) - sizeof(X)) + (sizeof(Z) - sizeof(X)) = 4 + 4 + 4 = 12,因为一个virtual base class X subobject只会在derived class中存在一份实例,不管它在class继承体系中出现了多少次;

2.2 win64平台

运行结果如下:

原因:

(1)class X:同win32;

(2)class Y 和 class Z内部首先存在一个继承而来的int(不分是否为virtual继承),其次存在一个指针,指向各自的virtual base class X subobject,64位机器中指针为8 bytes,按理说它们的大小应该是4 + 8 = 12,但存在alignment(传说中的内存对齐),在64位的机器上,通常alignment为8 bytes,以使bus的“运输量”达到最高效率(内存取址方便),所以class Y 和 class Z的大小为4 + 4(alignment) + 8 = 16;

(3)class A的大小更有意思,sizeof(A) = sizeof(X) + ( sizeof(Y) - sizeof(X) - 4(alignment) ) + ( sizeof(Z) - sizeof(X) - 4(alignment) ) = 4 + 8 + 8 = 20,另外需要4 bytes的alignment需要,总大小为4 + 4(alignment) + 8 + 8 = 24;

总结

主要对虚继承类的sizeof大小做了探讨,顺便学习了不同位数机器的内存对齐机制,希望对有需要的码农有所帮助,关于存在多态的虚继承请看我的这一篇博客https://blog.csdn.net/m0_38014304/article/details/84335787(VS是世界上最强大的IDE,但真的是太大了= =)

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值