直接继承和虚继承的内存布局

直接继承

(原文链接:点击打开链接

(1)无虚函数覆盖的单继承:

子类对象的内存布局:虚表指针、父类成员变量、子类成员变量

虚函数表的布局:父类的虚函数地址(按声明顺序)、子类自定义的虚函数的地址(按声明顺序)

(2)有虚函数覆盖的单继承

子类对象的内存布局:虚表指针、父类成员变量、子类成员变量
虚函数表的布局:子类已覆盖的虚函数的地址、父类中未被覆盖的虚函数的地址、子类自定义的虚函数的地址

(3)无虚函数覆盖的多继承

子类对象的内存布局:父类1的虚表指针、父类1的成员变量、父类2的虚表指针、父类2的成员变量
父类1虚函数表的布局:父类1的虚函数地址、子类自定义的虚函数的地址

父类2虚函数表的布局:父类2的虚函数地址

(4)有虚函数覆盖的多继承

子类对象的内存布局:父类1的虚表指针、父类1的成员变量、父类2的虚表指针、父类2的成员变量
父类1虚函数表的布局:子类已覆盖的虚函数的地址、父类中未被覆盖的虚函数的地址、子类自定义的虚函数的地址
父类2虚函数表的布局:子类已覆盖的虚函数的地址、父类中未被覆盖的虚函数的地址

总结:

直接继承的多继承中,继承了几个父类,就要维护几个虚函数表,并且为他们分配指针。

直接继承的多继承中,子类的自定义虚函数总是放在第一个父类的虚函数表的末尾。

直接继承的多继承中,如果发生菱形继承,那么子类对象的内存布局中不会做优化,比如说A派生B、C,D再多继承B、C,那么D类的对象会保存两个A类成员变量的副本。
但是虚继承的多继承中,如果发生菱形继承,那么
B对象的内存布局为:父类A的虚表指针、B自己的成员变量、父类A的成员变量
C对象的内存布局为:父类A的虚表指针、C自己的成员变量、父类A的成员变量
D对象的内存布局为:父类B的虚表指针、父类B的成员变量、 父类C的虚表指针、父类C的成员变量、D自己的成员变量、祖父类A的成员变量。
即只维护一个祖父类成员变量的副本,节省了空间。(引用链接:点击打开链接































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值