C++菱形继承产生二义性产生的原因(解决方法及简单案例)
问题:C++菱形继承产生二义性产生的原因(解决方法及简单案例)
本程序通过VC++ 6.0编译与测试,R为A,B的父类,A,B为C的父类,具体代码如下:
菱形继承的示意图:
//菱形继承产生的二义性
#include <iostream>
using namespace std;
//祖先类
class R
{
private:
int r;
public:
R(int i):r(i){};
void print()
{
cout<<"r="<<r<<endl;
}
};
//父类A
class A : public R
{
private:
int a;
public:
A(int int1,int int2):R(int2),a(int1){};
};
//父类B
class B: public R
{
private:
int b;
public:
B(int int1,int int2):R(int2),b(int1){};
};
//子类C
class C:public A,public B
{
private:
int c;
public:
C(int int1,int int2,int int3):A(int2,int3),B(int2,int3),c(int1){};
};
int main()
{
R rrr(10);
A aaa(20,30);
B bbb(40,50);
C ccc(60,70,81);
rrr.print();
aaa.print();
bbb.print();
ccc.print();//错误代码,编译器提示C中的print可能是由A继承的也可能是由B继承来的
return 0;
}
编译器报错:
//菱形继承产生的二义性的解决方案(使用虚继承)
#include <iostream>
using namespace std;
//祖先类
class R
{
private:
int r;
public:
R(int i):r(i){};
void print()
{
cout<<"r="<<r<<endl;
}
};
//父类A
class A : virtual public R
{
private:
int a;
public:
A(int int1,int int2):R(int2),a(int1){};
};
//父类B
class B: virtual public R //虚继承
{
private:
int b;
public:
B(int int1,int int2):R(int2),b(int1){};
};
//子类C
class C:public A,public B //虚继承
{
private:
int c;
public:
//C(int int1,int int2,int int3):A(int2,int3),B(int2,int3),c(int1){};
//构造函数先调用祖先类,再调用两个父类,再调用自身拓展的
C(int int1,int int2,int int3,int int4):R(int1),A(int2,int1),B(int3,int1),c(int4){};
};
int main()
{
R rrr(10);
A aaa(20,30);
B bbb(40,50);
C ccc(60,70,80,90);
rrr.print();
aaa.print();
bbb.print();
ccc.print();//此时可以正确运行,C中的r和print直接从祖先类中继承,此时只有一份祖先类的成员,不会出现二义性
return 0;
}
程序运行结果: