什麼是虛函式,我想如果你能馬上用口頭表達出來,那麼你的基礎不錯。知道虛函式表嗎?也許你已經看了很多書,了然於胸。其實很多時候並不需要看書,就可以體會到。然後什麼是虛擬繼承?也許聽說過,但很少使用。其實使用虛擬繼承,可以減輕你很多的痛苦。
看下面乙個例子:
這裡的例子盡可能的簡單,關於虛函式。
class father
void father::run()
void father::say()
;注意,為了避免歧義,int i已經是private 型別了。
int child::i=1;
child::child() : father()
;void child::say()
結果是什麼?
有經驗的人可能一眼就看出來了,我想,兩個say,應該都沒有問題。然後兩個建構函式,他輸出的是什麼?
可能有人說,virtual void run();不是虛擬的嗎?所以child y呼叫建構函式時,當然輸出的是1.
但馬上就會有人反駁,應該是0?,因為child::child() : father(),在構造father()的時候,child()還沒有構造,當然,child::i 的值不可能是1。
其實,結果不是這樣,輸出的是兩個2!為什麼? 虛函式失效了嗎? 其實不是的,原因很簡單,你要了解到i可不是虛擬的!而為什麼是輸出的是兩個father?這裡有兩種說法,1:在構造father的時候,child沒有構造,包括應該繼承的虛函式,2:因為father()本身就是father類的函式。所以,呼叫father類的方法。 其實這兩種說法是一致的。
class father
;int main()
結果是多少?100 而不是10, 這裡,建構函式完成工作後,再呼叫sayj,他呼叫的的確是child->sayj沒錯,是從father繼承過來的。但是,同樣j不是虛擬的,由於child中沒有重寫sayj,所以它會到「父類」中去找!一定要記住,虛函式不是巨集,它很智慧型,它知道sayj來自父類,所以j也來自父類。
有時候只要仔細一些這些小的錯誤,就可以避免。
現在就出一道題目了,看看你是否理解了e。其實就是第乙個例子的題目:
#include
using namespace std;
class father
void father::run()
void father::say()
;void child::say()
結果是多少?static 是故意迷惑你的。
結果是2
father
2father
2father
2child
對了嗎?
為什麼最後乙個是"child"? 因為say 在 child 中重寫過了!記住它很智慧型。
總結一下,在父類沒有構造好前,子類不會構造,包括應該繼承的虛函式!
即使構造了虛函式,虛函式不是巨集!它做的不是簡單的替換。
類變數不是虛擬的,建構函式不是虛擬的。(原理很簡單,只是有時候其他比較有趣的理論也講的通,增加了我們理解本質的難度)
好下面來說說虛擬繼承。如果你了解了虛函式那麼虛擬繼承也就不難了。
很簡單的例子。
class cwinbase : virtual protected igetproc
class cpaint : virtual protected igetproc,public cwinbase
好如果不用虛擬繼承,那麼igetproc 類,會出現什麼問題? 那就是ambiguous. 因為cwinbase中已經有了乙個igetproc了。(上面兩個定義的方式並不好,不要學習。)這樣做只是為了說明問題。為什麼可以除去ambiguous,其實原理和虛函式是一樣的。所謂虛擬,也就是當真正執行的時候,只有乙個實體。原理嘛,就去看看professional c++ ,裡面說的很詳細。
有時給自己一點提醒。不會犯可笑的錯誤
虛擬繼承 虛函式,含有虛函式的菱形虛擬繼承
一 虛擬繼承 虛函式 場景 派生類沒有自己的虛函式,只是繼承基類的虛函式 我們看乙個例子 class base virtual void funtest2 int b class derived virtual public base virtual void funtest2 int d type...
虛繼承和虛函式繼承
虛繼承主要用於菱形 形式的繼承形式 虛繼承是為了在多繼承的時候避免引發歧義,比如類 有個就是a,繼承了 c也繼承了 當 多繼承 時,就會有歧義產生了,所以要使用虛擬繼承避免重複拷貝。虛函式繼承是解決多型性的,當用基類指標指向派生類物件的時候,基類指標呼叫虛函式的時候會自動呼叫派生類的虛函式,這就是多...
虛基類 虛擬繼承 虛函式?
前幾天師兄想考我什麼是虛基類的時候,我說是因為多重繼承中,如果出現菱形繼承 multiple inheritance diamond 不想要末端派生類有兩份最底層基類的資料的話,就得用虛擬繼承。結果居然被懟了,說我說的啥玩意兒?我還以為我記錯了,實際上是他把虛基類和含有虛函式的基類給混淆了。今天讀了...