多重继承二义性的解决方法
多重继承、钻石继承、虚继承
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;
}