虛函式和虛擬繼承

2021-09-05 21:46:37 字數 1909 閱讀 4306

什麼是虛函式,我想如果你能馬上用口頭表達出來,那麼你的基礎不錯。知道虛函式表嗎?也許你已經看了很多書,了然於胸。其實很多時候並不需要看書,就可以體會到。然後什麼是虛擬繼承?也許聽說過,但很少使用。其實使用虛擬繼承,可以減輕你很多的痛苦。

看下面乙個例子:

這裡的例子盡可能的簡單,關於虛函式。

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 不想要末端派生類有兩份最底層基類的資料的話,就得用虛擬繼承。結果居然被懟了,說我說的啥玩意兒?我還以為我記錯了,實際上是他把虛基類和含有虛函式的基類給混淆了。今天讀了...