2.2 C++面向对象编程_多重继承

多重继承

所谓多重继承,就是有多个父类,或者说有多个基类。

创建两个基类Sofa和Bed,然后创建一个派生类SofaBed,沙发床。

需要注意一点,如果不是指明使用public方式继承,那么默认会使用private方式继承。

 在main函数中创建一个SofaBed的实例化对象s,然后分别调用watchTV函数和sleep函数。

测试结果如下,可以看到,SofaBed同时继承了两个基类Sofa和Bed:

多重继承的二义性

修改一下Sofa和Bed类,分别添加一个private成员weight,两个publick成员函数setWeight和getWeight。

修改后的Sofa类和Bed类如下:

此时如果通过s.getWeight调用getWeight函数,就会报错,因为编译器不知道需要调用的是哪个getWeight函数。

编译报错,因为编译器不知道要调用的是Sofa类还是Bed类的setWeight函数。

有一种解决的方法是,在调用时,指定调用哪个类的setWeight函数,比如指定调用Sofa类的setWeight函数。

此时编译就没有报错,但是不建议使用这种方法,或者说,这种问题出现的环境就是有问题的。

使用虚拟继承解决多重继承的二义性

可以使用虚拟继承的方式解决多重继承的二义性。

修改代码,增加一个Furniture类(家具类),将Sofa和Bed这些家具共有的属性放在家具类Furniture类中去。

然后使用虚拟继承的方式,由 Sofa 类和 Bed 类虚拟继承 Furniture 类。

 

这个时候,就可以在main函数中直接调用 setWeight 和 getWeight 函数了。

 

测试如下,符合预期:

虚拟继承时的内存分布

要理解为什么使用虚拟继承可以解决多重继承的二义性,需要先看一下虚拟继承时的内存分布。

为了方便分析内存分布,我们在三个类中分别添加一个私有成员a,b,c。

Sofabed类 继承于 Sofa 和 Bed,那么它的内存空间肯定有 Sofa 和 Bed 的部分,而 Sofa 和 Bed 由继承了 Furniture,所以他们的内存分布有 Furniture 类的部分。

 由于 Sofa 和 Bed 都是虚拟继承自 Furniture 类,所以 Sofa 类的 weight 和 Bed 类的 weight 实际上是同一个weight(同一个地址空间)。

也就是说,Sofabed类的实例化对象 s 的内存占用情况是这样的:

由于只有一个weight,所以自然就没有二义性。

总结

关于多重继承的总结如下:

  1. 一个派生类可以有多个基类;
  2. 多个基类可能引入一个问题——二义性;
  3. 解决二义性的方法——使用虚拟继承。虚基类使得多个类派生出的对象只继承一个基类对象,即:Sofabed 的基类 Sofa,Bed 共享一个 Furniture 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值