Bootstrap

多重继承二义性的解决方法

多重继承二义性的解决方法

多重继承、钻石继承、虚继承

1、多重继承
当一个类继承了多个父类时,称为多重继承,会按照继承表的顺序在子类中排列父类的内容,当把子类指针对象转换为父类指针时,编译器会自动计算出该父类内容所在的位置,并让指针偏移到该位置,因此,可能会出现转换后的父类指针与转换前子类指针不相同的情况
2、钻石继承
假如有一个类A,类B和类C都继承了类A,类D又同时继承了类B和类C,当子类的父类中有共同的祖先时,这种称为钻石继承
1、类B和类C中都各自有类A的内容
2、类D会继承类B和类C中的所有内容,就会导致类D中有两份类A的内容
3、当类D对象去访问类A中的成员时,编译器会产生歧义,不确定要使用的是哪份类A中的成员,因此编译不通过
3、虚继承
当使用 virtual 关键字修饰继承表时,此时变成虚继承,此时子类中就会多一个虚指针用于指向父类的内容,当这个子类被继承时,孙子类中也会继承该虚指针,并且通过虚指针比较是否含有多份相同的祖先类,如果有则只保留一份

在了解了这三种继承之后再回顾题目的问题,

​ 如果是多重继承:1.通过指定的继承路线

class A
{
  	public:
    	void func()
        {
            cout<<A::func<<endl;
        }
};
class B
{
    public:
    	void func()
        {
            cout<<B::func<<endl;
        }
};
class C:public A,public B
{
    
};

int main()
{
    C test;
    test.A::func();//指定为A
    return 0;
}


​ 2.同名覆盖

#include<iostream>
using namespace std;

class A
{
    public:
       void func()
      {
       cout<<"A::func() called"<<endl;
       }
};

class B
{
    public:
       void func()
        {
            cout<<"B::func() called"<<endl;
        }
};

class C:public A,public B
{
    public:
       void func()//子类中使用与父类相同名称的函数,覆盖。
        {
            cout<<"C::func() called"<<endl;
        }
};

int main()
{
    C c;
    c.func();
    return 0;

}

3.如果属于钻石继承,可以通过虚继承,解决二义性。

#include<iostream>
using namespace std;

class A
{
    public:
       void func()
      {
       cout<<"A::func() called"<<endl;
       }
};

class B:virtual public A
{

};

class C:virtual public A
{
    
};

class D:public:B,public:C
{
    
};

int main()
{
   D d;
    d.func();
    return 0;

}
;