1. 程式人生 > >C++ 多重繼承與虛繼承

C++ 多重繼承與虛繼承

在派生類中對基類成員的訪問應該是唯一的。但是,在多繼承情況下,可能造成對基類中某個成員的訪問出現了不一致的情況,這時就稱對基類成員的訪問產生了二義性。

原因之一:

   派生類在訪問基類成員函式時,由於基類存在同名的成員函式,導致無法確定訪問的是哪個基類的成員函式,因此出現了二義性錯誤。

例如:

	#include<iostream>
	using namespace std;
	
	
	class Base1
	{
	public:
		void fun(){cout<<"base1 "<<endl;};
	};
	
	class Base2
	{
	public:
		void fun(){cout<<"base2 "<<endl;};
	};
	
	class Derived:public Base1,public Base2{};
	
	int main()
	{
		Derived obj;
		obj.fun();   //產生歧義
		return 0;
	}


編譯時,會提示:

當派生類Derived訪問fun()函式時,無法確定訪問的是Base1的還是Base2的,將出現二義性錯誤。

解決辦法:

  1,使用作用域運算子指明訪問的是base1的還是base2的fun函式。

         例如:

                 obj.Base1::fun();   //指明訪問base1的fun函式

  2,在類中定義同名成員,使內層函式覆蓋外層的函式。

         例如:

class Derived:public Base1, public Base2
{
 
public:
 
    voidfun()
    {
        cout<<"使用的是內層的fun函式"<<endl;
    }
 
};

執行:

原因之二

     當一個派生類從多個基類派生時,而這些基類又有一個共同的基類,當對這個共同的基類中成員變數進行訪問時,可能出現二義性問題。

例如:

    Base為Derived11和Derived12的基類,而Derived2又繼承Derived11和Derived12,當Derived2訪問Base的data時,會出現二義性錯誤,程式碼如下:

class Base
{
public:
	int data;
};
 
class Derived11:public Base{};
class Derived12:public Base{};
 
class Derived2:public Derived11,public Derived12 {};
 
int main()
{
	Derived2 obj;
	obj.data=1;   //產生二義性
	return 0;
}

解決方法:

        1,作用域運算子

       Obj.Derived11::a,指明訪問哪一個基類的data.但是由於派生類的直接基類有一個共同的基類,所以 obj.Base::a是錯誤的。

2,使用虛基類

產生二義性的最主要的原因就是base在派生類Derived2中產生了2個物件,從而導致了對基類Base的成員data訪問的不一致性。要解決這個問題,只需使這個公共基類Base在派生類中只產生一個子物件即可。


雖然在形式上,Derived2繼承Derived11,Derived12,但是在儲存結構上,對data的訪問是指向Base的。