首先,虛函式的定義為在函式前新增關鍵字virtual。然後,之所以定義虛函式,是為了實現語言的多型性的特點。
虛函式裡面有純虛函式的玩意。通過直接在虛函式後面新增= 0來實現,舉例如下:
virtual void (*fun)() = 0;
應該注意的是,當乙個類中出現了至少乙個純虛函式時,這個類就成為了傳說中的抽象類。抽象類的特點是無法被例項化為乙個物件。原因就涉及到了純虛函式的特點。純虛函式表示這個虛函式還沒有實現,它要在這個類的派生類中具體的實現,然後它才可以被例項化。這個的好處就是提供介面,留著實現方法去等待實現,就像boss把任務介面給出,而具體的實現就讓員工去實現,而當員工沒有實現的時候,專案自然就無法實現了。
當乙個類出現了虛函式時,不管是純虛函式還是普通的虛函式,此時,類中都會出現乙個vptr的虛表指標。因此,這裡就會出現許多關於求類的大小的問題。特別注意,空類和只有普通類成員函式的類的大小為1,而出現純虛函式和虛函式時,則增加乙個指標型別的大小。這裡給出求虛表位址的求法。先給出**:
首先,我們定義了乙個包含虛函式的物件a。&a表示取得物件的位址,但是物件的位址不等於虛表的位址,雖然虛表位於物件的儲存塊的最開始位置。我們可以通過(int*)&a取得物件首元素的位址,即第一張虛表的位置。然後通過*引用,獲取虛表的第乙個元素,即指向fun1()的函式指標,此時,通過(int*)來強轉成整形指標位址型別,因為乙個指標的大小為4位元組,而後通過+1操作獲取下乙個虛函式的位址指標。所以,(int *)&a為虛表的位址,(int *)*(int *)&a為第乙個虛函式的位址。當需要呼叫這個虛函式時,先*引用這個虛函式指標,再加上(),如*(int*)*(int*)&a。
首先,分析簡單的虛繼承問題。當類中出現了純虛函式或虛函式時,此時派生類都會有兩種情況:派生類原來沒有虛表,繼承了父類的虛表;派生類原來有虛表,此時父類的虛表替換子類虛表,將子類虛表置入父表中,然後子類中的虛函式覆蓋父類中的同名虛函式。
虛函式,虛表,虛表指標
分享一篇文章,詳細解釋了為什麼通過基類指標指向基類物件或派生類物件,就可以呼叫相應類的虛函式。自 一 概述 為了實現c 的多型,c 使用了一種動態繫結的技術。這個技術的核心是虛函式表 下文簡稱虛表 本文介紹虛函式表是如何實現動態繫結的。二 類的虛表 每個包含了虛函式的類都包含乙個虛表。我們知道,當乙...
虛函式 虛指標和虛表
關於虛函式的背景知識 用virtual關鍵字申明的函式叫做虛函式,虛函式肯定是類的成員函式。存在虛函式的類都有乙個一維的虛函式表叫做虛表。類的物件有乙個指向虛表開始的虛指標。虛表是和類對應的,虛表指標是和物件對應的。多型性是乙個介面多種實現,是物件導向的核心。分為類的多型性和函式的多型性。多型用虛函...
虛函式 虛指標和虛表
關於虛函式的背景知識 用virtual關鍵字申明的函式叫做虛函式,虛函式肯定是類的成員函式。存在虛函式的類都有乙個一維的虛函式表叫做虛表。類的物件有乙個指向虛表開始的虛指標。虛表是和類對應的,虛表指標是和物件對應的。多型性是乙個介面多種實現,是物件導向的核心。分為類的多型性和函式的多型性。多型用虛函...