C++虛函數的完成機制剖析。本站提示廣大學習愛好者:(C++虛函數的完成機制剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是C++虛函數的完成機制剖析正文
本文針對C++的虛函數的完成機制停止較為深刻的剖析,詳細以下:
1、簡略地說,虛函數是經由過程虛函數表完成的。那末,甚麼是虛函數表呢?
現實上,假如一個類中含有虛函數,則體系會為這個類分派一個指針成員指向一張虛函數表(vtbl),表中每項指向一個虛函數的地址,完成上就是一個函數指針的數組。
例以下面這個例子:
class Parent { public: virtual void foo1() { } virtual void foo1() { } void foo1(); }; class Child1 { public: void foo1() { } void foo3(); }; class Child2 { public: void foo1() {} void foo2() {} void foo3(); };
上面列出了各個類的虛函數表(vtbl)的內容。
Parent類的vtbl:Parent::foo1( )的地址、Parent::foo1( )。
Child1類的vtbl:Child1::foo1( )的地址、Parent::foo1( )。
Child2類的vtbl:Child1::foo1( )的地址、Child2::foo1( )。
2、可以看出,虛函數表既有繼續性,又有多態性。每一個派生類的vtbl繼續了它各個基類的vtbl,假如基類vtbl中包括某一項,則派生類的vtbl中也將包括異樣的一項,然則兩項的值能夠分歧。假如派生類籠罩了該項對應的虛函數,則派生類vtbl的該指針先指向重載後的虛函數,沒有重載的話,則沿用基類的值。
3、在類對象的內存結構中,起首是該類的vtbl指針,然後才是對象數據。在經由過程對象指針挪用一個虛函數時,編譯器生成的代碼將先獲得對象類的vtbl指針,然後挪用vtbl中對應的項。關於經由過程對象指針挪用的情形,在編譯時代沒法肯定指針指向的是基類對象照樣派生類對象,或許是哪一個派生類的對象。然則在運轉時代履行到挪用語句時,這一點曾經肯定,編譯後的挪用代碼可以或許依據詳細對象獲得准確的vtbl,挪用准確地虛函數,從而完成多態性。
4、剖析一下這裡的思惟地點:
成績的本質是如許,關於收回虛函數挪用的這個對象指針,在編譯時代缺少更多的信息,而在運轉時代具有足夠的信息,但那時已不再停止綁定了,怎樣在兩者之間做一個過渡呢?
把綁定所需的信息用一種通用的數據構造記載上去,該數據構造可以同對象指針相接洽,在編譯時只須要應用這個數據構造停止籠統的綁定,而在運轉時代將會獲得真實的綁定。這個數據構造就是vtbl。可以看到,完成用戶所需的籠統和多態須要停止後綁定,而編譯器又是經由過程籠統和多態完成後綁定的。