c++ 多层继承分析

(1)首先我们考虑一个(非虚拟)多重继承的相对简单的例子。看看下面的C++类层次结构:

注意Top被继承了两次(在Eiffel语言中这被称作重复继承)。

这意味着类型Bottom的一个实例bottom将有两个叫做a的元素(分别为bottom.Left::a和bottom.Right::a)

那么Buttom 在内存中是如何存储的呢:编译器建议如下(当然也可以Right放在Left上面呢 如图):

下面开始测试:

     首先:

 接着测:如果我们提升Bottom指针,会发生什么事呢?

如果 再

 

原因就在于:(肯定是暗箱操作的 暂时不想追究了 下面“参考”) 如图 (注意访问域 一定是继承之间共有的可以访问)

是的,什么也没有。这条语句是有歧义的:编译器将会报错。

是的,什么也没有。这条语句是有歧义的:编译器将会报错。

(二)多继承(虚拟继承)

//首先:@https://www.cnblogs.com/jin521/p/5602190.html  //http://blog.csdn.net/stay_the_course/article/details/55259801

 

参考:1:http://blog.csdn.net/stay_the_course/article/details/55259801

  2:https://www.cnblogs.com/malecrab/p/5572730.html

3:https://www.cnblogs.com/jin521/p/5602190.html

4:http://blog.csdn.net/cmm0401/article/details/66472391

5:插入什么是多态:https://www.cnblogs.com/liujinhong/p/6003144.html

6:https://www.cnblogs.com/Daywei/p/5865342.html

7:汇编:https://www.cnblogs.com/lxgeek/archive/2011/01/01/1923738.html

 

虚继承和虚函数是完全无相关的两个概念。

虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。

虚继承可以解决多种继承前面提到的两个问题:

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

实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间

 

 

 

虚基类表存储的是虚基类相对直接继承类的偏移;而虚函数表存储的是虚函数地址。

 

理解虚继承:虚继承不同于真正的继承,多个派生类虚继承同一个基类,如图

 

 

菱形继承时:

转:c++ 对象模型:https://www.cnblogs.com/raichen/p/5744300.html

内存布局(看编译器)如下图:

访问被重复继承的基类时:如上图

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值