天天看点

C++的二义性和虚基类C++的二义性和虚基类

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

继续阅读