在c++中,派生類繼承基類,對基類成員的訪問應該是確定的、唯一的,但是常常會有以下情況導致訪問不一致,產生二義性。
1.在繼承時,基類之間、或基類與派生類之間發生成員同名時,將出現對成員訪問的不確定性——同名二義性。
2.當派生類從多個基類派生,而這些基類又從同乙個基類派生,則在訪問此共同基類中的成員時,將產生另一種不確定性——路徑二義性。1.
「倒三角」問題——同名二義性
#include "iostream"
using namespace std;
class parent_f
};class parent_m
};class son:public parent_f,public parent_m
};int main()
上面的**中,2個父類派生乙個子類,但兩個父類中都有同名的成員函式。派生出的子類產生二義性問題,編譯時會報:
error: request for member 'show' is ambiguous
解決方法:
(1)利用作用域限定符(::),用來限定子類呼叫的是哪個父類的show()函式
son.parent_f::show();
(2)在類中定義同名成員,覆蓋掉父類中的相關成員class son:public parent_f,public parent_m
「菱形」問題——路徑二義性
有最基類a,有a的派生類b、c,又有d同時繼承b、c,那麼若a中有成員a,那麼在派生類b,c中就存在a,又d繼承了b,c,那麼d中便同時存在b繼承a的a和c繼承a的a,那麼當d的例項呼叫a的時候就不知道該呼叫b的a還是c的a,就導致了二義性。
#include "iostream"
using namespace std;
class grandpa
;class parent_f:public grandpa {};
class parent_m:public grandpa {};
class son:public parent_f,public parent_m {};
int main()
grandpa為parent_f和parent_m的基類,而son又繼承parent_f和parent_m,當son訪問grandpa的year_old時,會出現二義性錯誤.
解決方法:
(1)使用作用域限定符,指明訪問的是哪乙個基類的成員。
注意:不能是grandpa作用域下限定,因為son直接基類的基類才是grandpa,縱使指明了訪問grandpa的成員的話,對於son來說,還是模糊的,還是具有二義性。
(2)在類中定義同名成員,覆蓋掉父類中的相關成員。
(3)虛繼承、使用虛基類
教科書上面對c++虛基類的描述玄而又玄,名曰「共享繼承」,名曰「各派生類的物件共享基類的的乙個拷貝」,其實說白了就是解決多重多級繼承造成的二義性問題。父類對祖父類的繼承方式改為虛繼承,那麼子類訪問自己從祖父類那裡繼承過來的成員就不會有二義性問題了,也就是將子類物件裡的祖父類物件統一為乙個,繼承的只有乙個祖父類物件,**如下。
#include "iostream"
using namespace std;
class grandpa
{public:
int year_old;
void show()
{cout << "year_old:" << year_old 使用了虛基類的方法,是不是感覺簡單方便多了呢
C 多繼承二義性問題
c 中的多繼承帶來的二義性問題 本文 出現二義性的原因 派生類在訪問基類成員函式時,由於基類存在同名的成員函式,導致無法確定訪問的是哪個基類的成員函式,因此出現了二義性錯誤。什麼是多重繼承的二義性 class a class b class c public a,public b 如果宣告 c c1...
繼承中的二義性問題
一 呼叫不同基類的同名成員時可能出現二義性 class a class b class c public a,public b 在執行obj.get 時將是有二義性的。因為類c分別從類a類b繼承了兩個不同版本的get 成員函式,因此,obj.get 到底呼叫哪個get 版本,編譯器將無從知曉。對於這...
C 多層繼承二義性問題
多繼承可以看作是單繼承的擴充套件。所謂多繼承是指派生類具有多個基類,派生類與每個基類之間的關係仍可看作是乙個單繼承。多繼承下派生類的定義格式如下 class 派生類名 繼承方式1 基類名1 繼承方式2 基類名2 其中,繼承方式1 繼承方式2 是三種繼承方式 public private protec...