一、菱形继承

        <1>定义:菱形继承就是多个类继承一个公共类,而这些派生类又同时被一个子类继承。如我们所想的几何菱形那样,如下图:A为父类,B,C为派生类,同时继承父类A,然后D又继承B和C,这样就构成一个菱形继承。

菱形继承与虚继承

        <2>代码展示:

菱形继承与虚继承

菱形继承与虚继承

        这里已经可以看出,当D里面的对象d调用fun()函数时,fun()函数下方已经出现红色波浪线,这是因为fun()函数是父类A的函数,B和C继承了A,也就继承了A里面的fun()函数,而D继承了B和C,当D里面的对象d调用fun()函数时,就会不知道调用的是谁的fun()函数。这就会产生“路径二义性”问题。

        注:二义性

        根据百度百科可知:如果文法G中的某个句子存在不止一棵语法树,则称该句子是二义性的。二义性又分为两种:同名二义性和路径二义性。上面所展示的代码就是“路径二义性”,同名二义性如下代码所示(A和B都有fun()函数,当C继承A和B,C中的对象c调用的fun()函数就会出现同名二义性,不知调用哪一个):

菱形继承与虚继承

        解决二义性问题,可以通过域限定,也就是当d调用fun()函数时,不像上面那样写,而死写成d.A::fun();这样就指明了调用的是A里面的fun()函数,就不会产生二义性。

<3>虚继承

        解决二义性还有一个方法,就是虚继承。虚继承是多重继承中的特有概念,虚拟基类为解决多重继承而出现。如最开始所画的图,图中A就是虚基类,实现方法就是给派生类B和C继承A的那一行的public A前面加上virtual即可。代码实现如下:

菱形继承与虚继承

        这样就可以解决二义性问题,与此同时,在B和C中都包含了一个指向A的虚基类指针列表vbptr(虚基表指针),其中记录的是从B和C的vbtable的首地址vbptr到A的元素之间的偏移量。此时不会生成各个子类的函数fun()标识,除非子类重写该函数,从而达到共享的目的。

相关文章:

  • 2020-01-30
  • 2021-12-15
  • 2019-11-26
  • 2018-05-27
  • 2021-12-05
  • 2021-09-10
  • 2021-09-14
猜你喜欢
  • 2020-02-12
  • 2018-10-23
  • 2018-10-26
  • 2020-03-25
  • 2021-12-04
  • 2020-06-08
  • 2021-10-17
  • 2021-09-02
相关资源
相似解决方案