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; }