c++————多继承菱形继承

多继承是c++特有的,然而这个特有也使得C++的麻烦比较多点,例如像菱形继承的二义性问题等等。而像java、python这些面向对象语言仅支持单继承。
一.继承
继承是C++完成复用的手段
1.单继承模式图:

这里写图片描述

2.多继承:多继承是建立在单继承的基础之上的一种继承机制,也就是子类有多个直接父类,继承模式图如下:

这里写图片描述

3.菱形继承:菱形继承之所以叫菱形继承,它来源于它的继承关系模型,这是根据它的模型形象的说明,下面便是菱形继承模式图:这里写图片描述
从菱形继承中可以看到单继承、多继承,所以菱形继承才是这里的重点,也是菱形继承复杂之处,它的复杂也带来不少的问题,通过了解底层我们就会发现菱形继承的问题
class A
{
public:
    int _a;
};
class B: public A
{
public:
    int _b;
};
class C: public A
{
public:
    int _c;
};
class D:public B,public C
{
public:
    int _d;
};
对象模型分析,如图所示:

这里写图片描述

内存储存分析:

这里写图片描述

不难看出,菱形继承中有俩个_a,上面我们的调用方式是对的原因在于 我们采用了类域限定符;那么当我们在下面这种场景下去调用_a时,势必会带来一些问题:
void test()
{
    D d;
    d._a=1;
    d._b=3;
    d._c=4;
    d._d=5;
}
①这段代码会出错,原因是访问_a时,不明确,因为编译器并不知道我们所访问的_a究竟是B还是C中的_a(二义性);②d对象中有俩个_a(B::_a && C::_a),造成资源的浪费(数据冗余);
对于这俩个缺点C++采用虚继承来解决。

2.虚继承

关键词virtual,将virtual加在继承方式前,如:class B:virtual public A;
代码如下:
class A
{
public:
    int _a;
};
class B:virtual public A
{
public:
    int _b;
};
class C:virtual public A
{
public:
    int _c;
};
class D:public B,public C
{
public:
    int _d;
};
类B、C虚继承A类,这样就避免了在D类中出现二义性、数据冗余,那么他到底是怎样实现的呢?下面我们先来看一下对象模型,并进行分析:

这里写图片描述

当我们对d对象中B的_a进行操作时会发现,C对象中的_a也在改变而且和B中的一样,这就说明了B::_a和C::_a是同一个元素,先来看一下底层(内存)吧!

这里写图片描述

当我们将所有元素对应其地址时会发现,蓝色的框里的东西,它们代表什么呢?进一步分析,发现好像是一段地址,试着取地址试一下:

这里写图片描述

我们会发现在这段地址下储存了一个零,再往下看四个字节,它分别储存了一个 14000000(10进制为20)0c000000(10进制为12)我们会发现:这里写图片描述
如上图分析,我们可知虚继承这一机制,是通过虚基表指针和虚基表 实现的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值