转自:https://www.cnblogs.com/tenjl-exv/p/7625484.html
多继承的二义性主要分为两种:
- 调用不同基类的同名成员时可能出现二义性
- 访问共同基类的成员可能出现二义性
1、调用不同基类的同名成员时可能出现二义性
class A
{
public:
void setA(int a);
int get();
private:
int a;
} ;
class B
{
public:
void setB(int b);
int get();
private:
int b;
} ;
class C:public A,public B
{
public:
void setC(int c);
int getC();
private:
int c;
};
在执行obj.get();时将是有二义性的。因为类C分别从类A类B继承了两个不同版本的get()成员函数,因此,obj.get();到底调用哪个get()版本,编译器将无从知晓。
有两种解决方法:
(1)使用作用域分辨符::加以消除。
obj.A::get();
obj.B::get();
(2)在类C中也定义成员函数get()函数,则有类C的对象obj访问get()函数obj.get()没有二义性,这是因为当派生类中的成员与基类中的成员重名时,派生类中的同名成员将被调用。
class A
{
public:
void setA(int a);
int get();
private:
int a;
} ;
class B
{
public:
void setB(int b);
int get();
private:
int b;
} ;
class C:public A,public B
{
public:
void setC(int c);
int get();
//此处改为这样
private:
int c;
};
2、访问共同基类的成员可能出现二义性
菱形继承问题
class A
{
public:
void disp();
private:
int a;
};
class B1:public A
{
public:
void dispB1();
private:
int b1;
};
class B2:public A
{
public:
void dispB2();
private:
int b2;
};
class C:public B1,public B2
{
public:
void dispC();
private:
int c;
};
在此类结构下,如果创建类C的对象c1:
C c1;
则下面的两个访问都有二义性:
c1.disp();
c1.A::disp();
不过下面的两条调用语句却是正确的:
c1.B1::disp();
c1.B2::disp();
解决方法:
采用虚基类的方式,代码如下:
class A
{
public:
void disp();
private:
int a;
};
class B1:virtual public A
{
public:
void dispB1();
private:
int b1;
};
class B2:virtual public A
{
public:
void dispB2();
private:
int b2;
};
class C:public B1,public B2
{
public:
void dispC();
private:
int c;
};