java 菱形继承_菱形继承与菱形虚拟继承

“菱形继承与菱形虚拟继承”

“继承”是c++面向对象语言的特点之一,对于一个类,我们如果想对这个类的功能进行扩充,这就可以通过"继承"的方式重新增添或删除这个类中的某些功能。C++语言支持单继承和多继承,如果不大清楚单继承和多继承的知识,不妨先看一下我以前的博客。正是因为c++支持这两种继承方式,所以才会出现菱形继承的方式。菱形继承顾名思义就是将单继承和多继承进行结合,形成的一种继承结构。下面是简单的菱形继承的图解:

4ea0225034a969bb238fd79c2fca28e1.png

这里有4个类分别是A、B、C、D。B和C都继承类A,我们把父类A也可称为“超类”,而类D又继承了B类和C类,下面是四个类中具体所包含的成员变量和成员函数:

class A

{

public:

virtual void fun1()

{

cout <

}

virtual void fun2()

{

cout <

}

virtual void fun3()

{

cout <

}

private:

int _a;

};

class B:  public A

{

public:

virtual void fun1()

{

cout <

}

virtual void fun3()

{

cout <

}

private:

int _b;

};

class C :  public A

{

public:

virtual void fun1()

{

cout <

}

virtual void fun3()

{

cout <

}

private:

int _c;

};

class D : public B, public C

{

public:

virtual void fun1()

{

cout <

}

virtual void fun3()

{

cout <

}

virtual void fun4()

{

cout <

}

private:

int _d;

};

在vs2013上面运行,进行监视能够看出菱形继承里面的内存布局如下:

4e384b2d72298010063d6eb8ba5d6480.png

我们能够看到对象d中有继承的类B和类C,其中类B和类C中都各自包括一个虚表指针,且指针的地址是不相同的,则两个类各自存在一个虚函数表。同时我们也能够看到菱形继承中,对象d中存在两个成员_a,这就存在问题,当我们想要访问_a时,编译器也不会知道我们想要访问的是哪一个变量,这就说明菱形继承存在一个“数据冗余”和“二义性“的问题。那么如何解决菱形继承所存在的这种问题呢?

“虚拟继承”可以解决菱形继承所存在的问题。所谓虚拟继承就是增加一个虚基表指针和偏移量,即就是将类B和类C继承改为虚拟继承:

class B:  virtual  public A

{}

class C :  virtual  public A

{}

对其进行监视,能够得到d的内存布局如下:

0da7682c778340e2862dfefdd528ff34.png

从这我们能够明显的看到,菱形虚拟继承比菱形继承的d中多存在一个指针,增加一个指针能够指向偏移量。

c++支持单继承和多继承,如果稍不注意就会出现菱形继承的问题,所以在写代码时尽量使用单继承。java语言设计的比较好,它只支持单继承,这就避免程序员在写代码时出错。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值