虛基類多重繼承建構函式規則
多重繼承也成mi,描述的是有多個直接基類的類。和單繼承一樣,公有mi表示的也是is-a關係。必須使用關鍵字public限定每乙個基類(除了非特別之處,編譯器預設為私有派生)
singerwaiter類繼承自singer和waiter,而singer和waiter有這共同的祖先worker。
包含基類元件worker的個數
在結構中,singer和waiter各自包含了乙個worker元件,所以在singerwaiter物件中包含了兩個worker
存在問題:
·二義性:
worker *p = &singerwaiterobj;
這時候p不知道指向的是singer包含的worker還是waiter包含的worker元件,有兩個位址可以選擇,因此產生二義性。
·二義性解決方法:使用型別轉換明確的指定物件
worker *pw1 = (waiter *) &singerwaiterobj;
worker *pw1 = (singer *) &singerwaiterobj;
·包含兩個worker物件拷貝還會導致其他問題虛基類使得從基類相同的多個類中派生出來的物件只繼承乙個基類物件。
virtual關鍵字放在』:』 後,基類名稱前。可以在public前也可以在public後
class
singer
:virtual
public worker;or
class
singer
:public
virtual worker
;
所以singerwaiter可以這麼定義
class
singer
:virtual
public worker
;class
waiter
:virtual
public worker
;class
singerwaiter
:public singer,
public waiter
;
為什麼使用術語虛
使用virtual(類似於關鍵字過載)不定義新關鍵字:防止新關鍵字與專案中的變數或者函式名重複,導致專案難以維護。
為什麼不拋棄將基類宣告為虛的這種方式,而使用虛行為成為多重繼承的準則呢
· ① 某些情況下需要基類的多個拷貝
· ② 如果基類預設為虛的話,程式需要完成額外的計算。因此需要用到虛基類再宣告是一種明智的選擇
是否存在麻煩
· 為了使得虛基類能夠工作,需要調整c++規則,並以不同形式編寫一些**;使用虛基類還可能需要修改已有**。
在包含虛基類的多重繼承中,基類和派生類之間的資訊自動傳遞就不起作用了。c++在基類是虛基類時,禁止資訊通過中間類自動傳遞給基類。
構造基類物件時,直接在派生類的初始值列表中呼叫繼承基類的建構函式即可。因為資訊可以通過中間類自動傳遞給基類。通過這種傳遞機制就可以依次正確的構造所需要的物件。
classa;
...}
;classb:
public a};
classc:
public b
};
因為c++在基類是虛基類時,禁止資訊通過中間類自動傳遞給基類。所以構造基類時候需要新的規則。
如已有的singerwaiter類,假設其建構函式如下:
singerwaiter
(const worker &wk,
int p=0,
int v = singer::other)
:worker
(wk)
,waiter
(wk,p)
,singer
(wk,v)
waiter(wk,p), singer(wk,v) 無法將wk的資訊傳遞給基類,因此這兩個建構函式只能構造waiter和singer派生類部分的成員。所以傳遞的wk資訊在這裡沒有作用。
顯式的呼叫虛基類的建構函式worker(const worker &wk)構造虛基類。如果不顯式呼叫,將使用預設worker的建構函式。
C 多重繼承 虛基類
使用多個基類的繼承被稱為多重繼承 mi mi描述的是有多個直接基類的類。與單繼承一樣,公有mi表示的也是 is a關係。mi帶來的兩個主要問題 1.從兩個不同的基類繼承同名方法。2.從兩個或更多相關基類那裡繼承同一類的多個例項。例如 singer 和 waiter都繼承了乙個worker 元件,因此...
C 多重繼承與虛基類
多重繼承就是乙個派生類繼承了多個基類。i 通過成員初始化列表指定建構函式 class d public b,public c ii 構造函式呼叫順序 class b void f class c void f class d public b,public c void f int main 輸出 ...
多重繼承 虛繼承與虛基類
一 多重繼承 單重繼承 乙個派生類最多只能有乙個基類 多重繼承 乙個派生類可以有多個基類 class 類名 繼承方式 基類1,繼承方式 基類2,派生類同時繼承多個基類的成員,更好的軟體重用 可能會有大量的二義性,多個基類中可能包含同名變數或函式 多重繼承中解決訪問歧義的方法 基類名 資料成員名 或成...