c++ 对象内存布局

  1. c++ 继承是如何分配对象空间的?
  • class Derived:public Base1,private Base2,protected Base3,在这样的情况下,内存布局与可访问修饰无关,依次放Base1,Base2,Base3,Derived.
  • c++ 对象中的内存对齐。char无对齐,short默认2字节对齐,int默认4字节对齐,long long默认8字节对齐。默认情况下,32位程序对象首地址,4字节对齐,64位程序对象首地址8字节对齐。当两个char型分配在一起时,只有第一个是对齐的,第二个开始紧挨着放,而当类型不同时,会在中间插入空隙保证对齐性。__declspec(align(8)),显式对齐msvc,__attribute__((__aligned__(n))),g++.
  • 当具有虚继承时,class Derived: virtual public Base1,private Base2,protected Base3,先放Base2,再放Base3,再放Derived,最后放Base1,注意,Derived头部会有一个虚基指针。
  1. 虚函数表中的函数是按什么顺序摆放的?
  • 首先直接对一个虚函数&A::virtualfunc是无法取到其地址的,取出的一个数在不同编译器下有不同表现,不知道其含义,不能用。将 class Derived:public Base1,private Base2,protected Base3中的,如果Base1有虚函数,则Base1的布局开头是一个vfptr,Base2,Base3同理,当Derived中重写Base中的虚函数时,Base中将使用被重写的函数的地址,而当Derived中定义新的虚函数时,此时,Derived头部不会生成新的虚函数表,而是将其添加到Base1的虚函数表的后面。在所有的虚函数中,它们一般按定义先后顺序排列,但是虚函数一般放在虚函数表的表头,如果虚函数表是接在基类后边的,那虚函数也是接在后边的位置中的第一个。也就是说,其实虚函数不一定在虚函数表的表头(当它借用Base类的虚函数表的时候)。

总结:

  • 内存分布不受public,private,protected影响。
  • 继承时,先放class Derived:Base1,Base2,virtual Base3,Base4,先放不带virtual的Base,再放Derived,最后放virtual Base。即Base>Derived>virtual Base
  • 虚函数表,虚函数表的优先级高于虚基表,即有虚基表时,虚基表只能跟在虚函数表后面,每个带有虚函数的Base均有一个虚函数表,位于Base分布位置的开头,Derived的虚函数表一般直接加在第一个Base后边(此时,Derived的析构函数就不在表的开头了,而是追加位置的开头)。没有Base带有虚函数时,就在类的内存开头创建一个虚函数表。
  • 虚基表,虚基表位于Derived分布的开头,优先级低于虚基表,其表中第一个元素是当前位置相对于表头的偏移,一般是个负值,而后的元素是各个虚基类相对于当Derived的偏移,这是个正值。

提练:
两个优先级: 实父亲>类本身>虚父亲,虚函数表>虚基表
一个借用 :对象本身的虚函数可以跟在其第一个有虚函数实父亲的虚表后面。
顺序 :书写顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值