C++的二义性和虚基类
一、二义性问题
1.在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性。
2.当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生另一种不确定性——路径二义性。
二、同名二义性
同名隐藏规则——解决同名二义的方法
1、当派生类与基类有同名成员时,派生类中的成员将屏蔽基类中的同名成员。
2、若未特别指明,则通过派生类对象使用的都是派生类中的同名成员;
3、如要通过派生类对象访问基类中被屏蔽的同名成员,应使用基类名限定(::)。
三、路径二义性
虚基类规则-------解决路径二义性的方法
1、派生对象时使基类成为虚基类,可以解决路径二义性的问题;
四、举例说明
1、同名二义性
#include <iostream>
using namespace std;
class B0
{
public:
B0(int b0)
{
m_b0 = b0;
cout << "B0 construction" << endl;
}
void fun()
{
cout << "fun of BO" << endl;
}
private:
int m_b0;
};
class B1 : public B0
{
public:
B1(int b0, int b1) : B0(b0)
{
m_b1 = b1;
cout << "B1 construction" << endl;
}
void fun()
{
cout << "fun of B1" << endl;
}
private:
int m_b1;
};
int main()
{
B1 b(1, 2);
b.fun(); //访问B1的fun()
b.B0::fun(); //访问B0的fun()
return 0;
}
2、路径二义性
#include <iostream>
using namespace std;
class B0
{
public:
B0(int b0)
{
m_b0 = b0;
cout << "B0 construction" << endl;
}
void fun()
{
cout << "fun of BO" << endl;
}
private:
int m_b0;
};
class B1 : virtual public B0
{
public:
B1(int b0, int b1) : B0(b0)
{
m_b1 = b1;
cout << "B1 construction" << endl;
}
private:
int m_b1;
};
class B2 : virtual public B0
{
public:
B2(int b0, int b2) : B0(b0)
{
m_b2 = b2;
cout << "B2 construction" << endl;
}
private:
int m_b2;
};
class D0 : public B1, public B2
{
public:
D0(int b0, int b1, int b2, int d0) : B0(b0), B1(b0, b1), B2(b0, b2)
{
m_d0 = d0;
cout << "D0 construction" << endl;
}
void fun()
{
cout << "fun of DO" << endl;
}
private:
int m_d0;
};
int main()
{
D0 d(1, 2, 3, 4);
d.fun(); //访问D0的fun()
return 0;
}