【C++总结记载】类对象、继承、虚继承、虚函数表

关于虚函数表,可见博客    传送    ,但是要注意,一般被继承的第一个基类的虚函数表合并至子类的虚函数表,(基类的虚函数在前,除非有虚函数覆盖,子类的虚函数在后)

主要讲了在无虚继承情况下各种情况的虚函数表的情况,

因此,就牵扯到了类的大小的问题:

1)对于一个空类,sizeof=1;

2)静态成员不属于类大小中,且成员函数也不属于类大小中

3)类与继承情况下类的大小:

情况一:   无虚函数继承,但有虚函数的情况

class A 
{
public:
	char a[3];	
	virtual void fa() {};
};

class B :  public  A
{
public:
	char b[3];
	virtual void fa() {};
	
};

class C : public  A
{
public:
	char c[3];	
	virtual void bb() {};
};


int main() {
	
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	cout << sizeof(C) << endl;
}

结果是:VS2015   debug   x86

sizeof(A) = 8   

              = A的虚函数表指针的4字节+char对齐的4字节

 

sizeof(B) = 12   

              = B的虚函数表指针的4字节 + 类B中char对齐的4字节+类A中char对齐的4字节 

 

sizeof(C) = 12   

              = C的虚函数表指针的4字节 + 类C中char对齐的4字节+类A中char对齐的4字节 

情况二:   虚函数继承,有虚函数的情况

class A 
{
public:
	char a[3];	
	virtual void fa() {};
};

class B :  virtual public  A
{
public:
	char b[3];
	virtual void fa() {}; //虚函数覆盖
	
};

class C : virtual public  A
{
public:
	char c[3];	
	virtual void bb() {}; //无虚函数覆盖
};

class D :public B, public C
{
public:
	char d[3];
	
};

int main() {
	
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	cout << sizeof(C) << endl;
	cout << sizeof(D) << endl;
}

 

虚继承:虚继承的提出是为了解决多重继承时,可能会保存两份副本的问题,也就是说用了虚继承就只保留了一份副本,但是这个副本是被多重继承的基类所共享的。

 

虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。

因此 :要考虑虚函数表指针和虚基类指针

 

结果是:VS2015   debug   x86

sizeof(A) = 8   

              = A的虚函数表指针的4字节+char对齐的4字节

sizeof(B) = 16  

              =  指向A的虚基类指针4字节+类B中char对齐的4字节  + 类A的虚函数表指针4字节(覆盖的虚函数)+ 类A中char对齐的4字节

sizeof(C) = 20   

              = C的虚函数表指针的4字节(没有覆盖的虚函数) +指向A的虚基类指针4字节+类C中char对齐的4字节 + 类A的虚函数表指针4字节 + 类A中char对齐的4字节

sizeof(D) = 32

             = 类C的虚函数表指针的4字节(有虚函数表指针,可以合并类D的虚函数)+类C中的指向A的虚基类指针4字节 +类C中char对齐的4字节+类B中的指向A的虚基类指针4字节 +类B中char对齐的4字节+类D中char对齐的4字节 + 共享类A中虚函数表指针4字节+共享类A中char对齐的4字节

 

注意:若类B中有虚函数表指针,则类D中类B应该在类C的前边,并且类B的虚函数表应该合并类D的虚函数表

 

 

由上可见,虚基类的内存都在最后。。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值