菱形继承问题和虚继承

绝地灬酷狼 2022-03-18 02:58 338阅读 0赞

一、C++的菱形继承 

  1. 假设有类B和类C,它们都继承了相同的类A。另外还有类D,类D通过多重继承机制继承了类B和类C

   如果直接继承会引发访问不明确(二义性),以及数据冗余。如果直接指定访问对象,可解决二义性,而要解决数据冗余,则要引入虚函数。

   因为图表的形状类似于菱形(或者钻石),因此这个问题被形象地称为菱形问题(钻石继承问题)。

   1023530-20171128220616940-689764561.png

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. class Base{
  4. public:
  5. void fun(){
  6. cout<<"Base()"<<endl;
  7. }
  8. };
  9. class A:public Base{
  10. };
  11. class C:public Base{
  12. };
  13. class D:public A,public C{
  14. };
  15. int main(){
  16. D d;
  17. //d.fun(); 出错,返回request for member 'fun' is ambiguous
  18. d.A::fun();
  19. d.C::fun();
  20. return 0;
  21. }

可以看到,如果不利用域限定需要访问的函数,那么就会出现模糊调用的问题,但是貌似C++给了更好的方法,虚继承!

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. class Base{
  4. public:
  5. int _base=1;
  6. void fun(){
  7. cout<<"Base()"<<endl;
  8. }
  9. };
  10. class A:virtual public Base{
  11. public:
  12. int _base=2;
  13. };
  14. class C:virtual public Base{
  15. public:
  16. int _base=3;
  17. };
  18. class D:public A,public C{
  19. };
  20. int main(){
  21. D d;
  22. d.fun();//Base()
  23. d.A::fun();//Base()
  24. d.C::fun();//Base()
  25. cout<<d.Base::_base<<endl;//1
  26. cout<<d.A::_base<<endl;//2
  27. cout<<d.C::_base<<endl;//3
  28. return 0;
  29. }
  30. 利用虚继承就可以解决菱形继承的问题,具体实现是:BC中不再保存Base的具体内容,而是保存了一份偏移地址,所以在D调用fun()时,调用的就是Afun(),但对于BC相同的变量名,D在调用时还是要利用域限定来处理。虚继承不同于虚函数,虚函数在C++中主要用于实现多态,具体见:[虚函数][Link 1]、[动态绑定和静态绑定][Link 2]。

二、java为何没有多继承

  1. 假设类A中有一个public方法fun(),然后类B和类C同时继承了类A,类B或类C中各自对fun()进行了覆盖,这时类D通过多继承同时继承了类B和类C,这样便导致砖石危机了,程序在运行的时候对应方法fun()该如何判断?

(1)如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
(2)如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。

java为了避免C++的菱形继承问题,简单粗暴的去除了菱形继承问题。

发表评论

表情:
评论列表 (有 0 条评论,338人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++:53---菱形继承继承

    一、菱形继承 在介绍虚继承之前介绍一下菱形继承 概念:A作为基类,B和C都继承与A。最后一个类D又继承于B和C,这样形式的继承称为菱形继承 菱形继承的缺

    相关 菱形继承问题

      在java中只允许单继承,至于原因就需要牵扯到“菱形继承问题”。 菱形继承问题   在介绍之前首先看一张图:   ![在这里插入图片描述][watermark_