今天看程序员面试宝典,发现一道sizeof与类的长度有关的试题,于是动手实验了一下,发现还挺有趣。
当然,那本书上所讲的东西略浅显,我个人进行了一些总结与挖掘!!
①空类大小为1,多重继承的空类大小也为1,其实说到底,大小为1只是为了表现出这个类的存在,否则大小为0,连内存分配都没有,类就根本不存在了。
②类中含有虚函数则类的长度(sizeof计算)增加一个指针长度。因为这里涉及到虚表,需要用一个指针指向虚表。
③类中的私有/公有/保护变量能够改变类的大小,一般都使用了内存对齐机制。
④继承类的性质如上,但是这仅仅是指实继承,如果是虚继承则是另一回事了。
。。。。。
前提条件,在我的机器上:sizeof(int) = 4,sizeof(int*) = 8.内存是以8个字节为单位对齐的。(64位系统)
现在进行测试,毕竟语言略显苍白。
class A
{
public:
virtual void f() {}
virtual void g() {}
int y;
int z;
private:
int k;
int h;
protected:
char zz;
};
sizeof(A)的长度是多少??答案是32,有了虚函数便有了虚表,需要一个指向这个虚表的指针,大小为8,虚函数的多少对大小是没有影响的,5个变量,由于内存对齐的关系,4个整型16个字节,1个char型8个字节,一共是32个字节。
下面进行继承方面的测试,增加如下代码:
class B: public A
{
};
我们发现sizeof(B) = sizeof(A) = 32,毕竟构造继承类需要先构造基类。
改写继承类B为如下代码:
class B: public A
{
public :
virtual void ff() {}
private:
int kk;
int hh;
protected:
char zzz;
};
此时sizeof(B) = 40,即5个指针长度,为什么呢?原因是除了包含基类的4个指针长度外,对B而言又新增了2个整型变量和1个char型变量,基类的char型变量压缩到4个字节了,2个整型变量占8个字节,1个char型变量占4个字节,正好40个字节。
接下来探讨最后一个重点:虚继承(共享继承)
class B: public virtual A
{
public :
virtual void ff() {}
private:
int kk;
int hh;
protected:
char zzz;
};
如上代码只是把B的继承方式增加了一个virtual,但是此时sizeof(B) = 56,一下就增加了这么多!!!why??原因是增加了一个虚类指针,8个字节,2个整型变量占用8个字节,1个char型变量占用8个字节,至于为什么如此是因为此时内存分配与上面是完全不一样的,想了解更多需要去看看虚继承与普通继承的区别。