C 虛函式 虛函式表位址

2021-08-29 18:38:46 字數 1861 閱讀 8538

總結自:

編譯器:vs2017

一、虛函式

當我們使用基類的引用或者指標呼叫乙個虛成員函式時會執行動態繫結,直到執行時才知道到底呼叫了哪個版本的虛函式,被呼叫的函式是與繫結到指標或者引用上的物件的動態型別相匹配的那乙個。所有虛函式都必須有定義。虛函式的作用主要是實現多型機制。

using namespace std;

class base

private:

int a;

};class derive :public base

};void display(base* ptr)

int main()

上面輸出結果為 funa of base 和 funa of derive;函式display()接受乙個基類指標引數,通過指標呼叫虛成員函式funa(),當基類指標指向乙個基類物件例項時,呼叫的是基類的成員函式funa();當基類指標指向乙個派生類物件例項時,呼叫的是派生類的成員函式funa()。如果funa()為非虛函式,則上面程式中display()呼叫的函式都為基類的funa(),因為基類指標只能訪問呼叫基類的成員,即使這個基類指標指向的是乙個子類的物件例項。

二、虛函式表

虛函式是通過虛函式表實現的,虛函式表實際上是乙個儲存類中虛函式位址的陣列。

當類中存在虛函式時,這個類的物件例項就會有乙個指向虛函式表的指標,同屬於乙個類的物件共享虛函式表,在c++的標準規格說明書中說到,編譯器必需要保證虛函式表的指標存在於物件例項中最前面的位置(這是為了保證正確取到虛函式的偏移量)。 這意味著我們通過物件例項的位址得到這張虛函式表,然後就可以遍歷其中函式指標,並呼叫相應的函式。

當通過指標呼叫類中的虛函式時,會根據指標所指物件的虛函式表位址訪問虛函式表,找到相應的虛函式。

using namespace std;

class a

void funb()

void func()

private:

int a;

};class base

virtual void funb()

virtual void func()

private:

int a;

};int main()

下面的程式是通過虛函式表呼叫虛函式

using namespace std;

class base

virtual void funb()

virtual void func()

private:

int a;

};class derive :public base

virtual void funb()

virtual void func()

};int main()

輸出結果為"funa of base" 、"func of base"、"funa of derive"。即通過函式指標呼叫虛函式。

說明:vs2017中虛函式表指標在物件中佔四個位元組,虛函式指標佔四個位元組;

(int*)(&b)指向物件例項的int型別指標;

*(int*)(&b)就是虛函式表的位址,int型別佔4個位元組,解引用int型別指標讀取位址前四個位元組,(int*)*(int*)(&b)轉換為int型別的指標;

(int*)*((int*)*(int*)(&b))為虛函式表第乙個虛函式的位址;

(int*)*(int*)(&b)與*(int*)(&b)指向的位置是一樣的,(int*)*(int*)*(int*)(&b)與*(int*)*(int*)(&b)指向的位置也是一樣的。

暫時這些,後續再補充修改g++下的情況。

虛函式表指標,虛函式表

對c 了解的人都應該知道虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的。簡稱為v table。在這個表中,主是要乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其容真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了 這個例項...

C 虛函式與虛函式表

概念 虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的,簡稱為v table。學習虛函式的作用 理解 c 實現多型的機制 解決了繼承 覆蓋的問題。以下摘抄自 http www.cppblog.com xczhang archive 2008 01 2...

C 虛函式指標虛函式表

c 的多型可以分為靜態多型和動態多型。函式過載和運算子過載實現的多型屬於靜態多型,而通過虛函式可以實現動態多型。實現函式的動態聯編其本質核心則是虛表指標與虛函式表。1.虛函式與純虛函式區別 1 虛函式在子類裡面也可以不過載的 但純虛必須在子類去實現 2 帶純虛函式的類叫虛基類也叫抽象類,這種基類不能...