多繼承可以看作是單繼承的擴充套件。所謂多繼承是指派生類具有多個基類,派生類與每個基類之間的關係仍可看作是乙個單繼承。
多繼承下派生類的定義格式如下:
class 《派生類名》:《繼承方式1>《基類名1>,《繼承方式2>《基類名2>,… ; 其中,《繼承方式1>,《繼承方式2>,…是三種繼承方式:public、private、protected之一。例如: class a ; class b ; class c : public a, public b ;
其中,派生類c具有兩個基類(類a和類b),因此,類c是多繼承的。按照繼承的規定,派生類c的成員包含了基類a, b中成員以及該類本身的成員。
多繼承的建構函式
在多繼承的情況下,派生類的建構函式格式如下:
《派生類名》(《總參數列》):《基類名1>(《參數列1>),《基類名2>(《參數列2>),…
《子物件名》(《參數列n+1>),…
其中,《總參數列》中各個引數包含了其後的各個分參數列。
多繼承下派生類的建構函式與單繼承下派生類建構函式相似,它必須同時負責該派生類所有基類建構函式的呼叫。同時,派生類的引數個數必須包含完成所有基類初始化所需的引數個數。
派生類建構函式執行順序是先執行所屬基類的建構函式,再執行派生類本身建構函式,處於同一層次的各基類建構函式的執行順序取決於定義派生類時所指定的各基類順序,與派生類建構函式中所定義的成員初始化列表的各項順序無關。也就是說,執行基類建構函式的順序取決於定義派生類時基類的順序。可見,派生類建構函式的成員初始化列表中各項順序可以任意地排列。
下面通過乙個例子來說明派生類建構函式的構成及其執行順序。
#include class b1 ;
class b
;class c : public a, public b
;如果定義乙個類c的物件c1:
c c1;
則對函式f()的訪問
c1.f();
便具有二義性:是訪問類a中的f(),還是訪問類b中的f()呢?
解決的方法可用前面用過的成員名限定法來消除二義性,例如:
c1.a::f();
或者c1.b::f();
但是,最好的解決辦法是在類c中定義乙個同名成員f(),類c中的f()再根據需要來決定呼叫a::f(),還是b::f(),還是兩者皆有,這樣,c1.f()將呼叫c::f()。
同樣地,類c中成員函式呼叫f()也會出現二義性問題。例如:
viod c::h() 這裡有二義性問題,該函式應修改為: void c::h() 或者 void c::h() 或者 void c::f()
另外,在前例中,類b中有乙個成員函式g(),類c中也有乙個成員函式g()。這時,
c1.g();
不存在二義性,它是指c::g(),而不是指b::g()。因為這兩個g()函式,乙個出現在基類b,乙個出現在派生類c,規定派生類的成員將支配基類中的同名成員。因此,上例中類c中的g()支配類b中的g(),不存在二義性,可選擇支配者的那個名字。
當乙個派生類從多個基類派生類,而這些基類又有乙個共同的基類,則對該基類中說明的成員進行訪問時,也可能會出現二義性。例如:
class a
;class b1 : public a
;class b2 : public a
;class c : public b1, public b2
;已知:c c1;
下面的兩個訪問都有二義性:
c1.a;
c1.a::a;
而下面的兩個訪問是正確的:
c1.b1::a;
c1.b2::a;
類c的成員函式f()用如下定義可以消除二義性:
int c::f()
由於二義性的原因,乙個類不可以從同乙個類中直接繼承一次以上,例如:
class a : public b, public b
這是錯誤的。
C 多層繼承二義性問題
多繼承可以看作是單繼承的擴充套件。所謂多繼承是指派生類具有多個基類,派生類與每個基類之間的關係仍可看作是乙個單繼承。多繼承下派生類的定義格式如下 class 派生類名 繼承方式1 基類名1 繼承方式2 基類名2 其中,繼承方式1 繼承方式2 是三種繼承方式 public private protec...
C 多繼承二義性問題
c 中的多繼承帶來的二義性問題 本文 出現二義性的原因 派生類在訪問基類成員函式時,由於基類存在同名的成員函式,導致無法確定訪問的是哪個基類的成員函式,因此出現了二義性錯誤。什麼是多重繼承的二義性 class a class b class c public a,public b 如果宣告 c c1...
C 二義性問題
二義性問題 1.在繼承時,基類之間 或基類與派生類之間發生成員同名時,將出現對成員訪問的不確定性 同名二義性。2.當派生類從多個基類派生,而這些基類又從同乙個基類派生,則在訪問此共同基類中的成員時,將產生另一種不確定性 路徑二義性。同名二義性 同名隱藏規則 解決同名二義的方法 當派生類與基類有同名成...