淺談虛擬函式表與位元組對齊
一、虛擬函式的工作原理
虛擬函式的實現要求物件攜帶額外的資訊,這些資訊用於在執行時確定該物件應該呼叫哪一個虛擬函式。典型情況下,這一資訊具有一種被稱為
vptr(virtual table pointer,虛擬函式表指標)的指標的形式。vptr 指向一個被稱為 vtbl(virtual
table,虛擬函式表)的函式指標陣列,每一個包含虛擬函式的類都關聯到
vtbl。當一個物件呼叫了虛擬函式,實際的被呼叫函式通過下面的步驟確定:找到物件的
vptr 指向的 vtbl,然後在 vtbl 中尋找合適的函式指標。
虛擬函式的地址翻譯取決於物件的記憶體地址,而不取決於資料型別(編譯器對函式呼叫的合法性檢查取決於資料型別)。如果類定義了虛擬函式,該類及其派生類就要
生成一張虛擬函式表,即vtable。而在類的物件地址空間中儲存一個該虛表的入口,佔4個位元組,這個入口地址是在構造物件時由編譯器寫入的。所以,由於
物件的記憶體空間包含了虛表入口,編譯器能夠由這個入口找到恰當的虛擬函式,這個函式的地址不再由資料型別決定了。故對於一個父類的物件指標,呼叫虛擬函式,
如果給他賦父類物件的指標,那麼他就呼叫父類中的函式,如果給他賦子類物件的指標,他就呼叫子類中的函式(取決於物件的記憶體地址)。
二、(虛)繼承類的記憶體佔用大小
首先,平時所宣告的類只是一種型別定義,它本身是沒有大小可言的。 因此,如果用sizeof運算子對一個型別名操作,那得到的是具有該型別實體的大小。
計算一個類物件的大小時的規律:
1、空類、單一繼承的空類、多重繼承的空類所佔空間大小為:1(位元組,下同);
2、一個類中,虛擬函式本身、成員函式(包括靜態與非靜態)和靜態資料成員都是不佔用類物件的儲存空間的;
3、因此一個物件的大小≥所有非靜態成員大小的總和;
4、當類中宣告瞭虛擬函式(不管是1個還是多個),那麼在例項化物件時,編譯器會自動在物件裡安插一個指標vPtr指向虛擬函式表VTable;
5、虛承繼的情況:由於涉及到虛擬函式表和虛基表,會同時增加一個(多重虛繼承下對應多個)vfPtr指標指向虛擬函式表vfTable和一個vbPtr指標指向虛基表vbTable,這兩者所佔的空間大小為:8(或8乘以多繼承時父類的個數);
6、在考慮以上內容所佔空間的大小時,還要注意編譯器下的“補齊”padding的影響,即編譯器會插入多餘的位元組補齊;
7、類物件的大小=各非靜態資料成員(包括父類的非靜態資料成員但都不包括所有的成員函式)的總和+ vfptr指標(多繼承下可能不止一個)+vbptr指標(多繼承下可能不止一個)+編譯器額外增加的位元組。
三,位元組對齊
寫出一個含有資料成員的類,然後sizeof ,sizeof的結果總要比資料成員的總長度大,這就是因為位元組對齊。
我們知道在一個沒有虛擬函式的類中,其物件大小就是其資料成員的長度,當我們sizeof這個類的物件的時候,其值往往比我們悽婉的要大,比如,我們有一個類擁有一個int 和一個char型別的資料成員
class{
int no;
char key;
}
然後sizeof這個類的物件,我們會發現結果是8而不是我們想的5.這就是因為位元組對齊。對齊和不對齊,是在時間和空間上的一個權衡。為了提高效率,計算機從記憶體中取資料是按照一個固定長度的。以32位機為例,它每次取32個位,也就是4個位元組(每位元組8個位,計算機基礎知識,別說不知道)。位元組對齊有什麼好處?以int型資料為例,如果它在記憶體中存放的位置按4位元組對齊,也就是說1個int的資料全部落在計算機一次取數的區間內,那麼只需要取一次就可以了。這樣效率就得到了提高。
推薦文章:http://www.tuicool.com/articles/Jrq6bai (物件記憶體佈局)
C語言記憶體位元組對齊小結 - andy572633的專欄 - 部落格頻道 - CSDN.NET (c語言記憶體位元組對齊)
相關文章
- 位元組對齊小談
- 虛擬函式,虛擬函式表函式
- 位元組對齊
- C++中的虛擬函式與虛擬函式表 (轉)C++函式
- golang 位元組對齊Golang
- C++ 位元組對齊C++
- <摘錄>位元組對齊(強制對齊以及自然對齊)
- c/c++ 位元組對齊C++
- 記憶體位元組對齊記憶體
- <摘錄>位元組對齊與結構體大小結構體
- jvm 虛擬機器位元組碼指令表JVM虛擬機
- c++虛擬函式表C++函式
- 虛擬函式 純虛擬函式函式
- 【C++筆記】虛擬函式(從虛擬函式表來解析)C++筆記函式
- iOS 記憶體位元組對齊iOS記憶體
- C++ 虛擬函式表剖析C++函式
- 虛擬函式與多型函式多型
- 【C++】C++的位元組對齊C++
- C++ 虛擬函式和虛繼承淺析C++函式繼承
- C++多型(上)——虛擬函式、虛表C++多型函式
- 介面、虛擬函式、純虛擬函式、抽象類函式抽象
- 虛擬函式函式
- 深入C++成員函式及虛擬函式表C++函式
- C++物件導向總結——虛指標與虛擬函式表C++物件指標函式
- 我對C++中虛擬函式、純虛擬函式在實現多型中作用的一點淺薄認識 (轉)C++函式多型
- 單位元組處理函式函式
- 虛擬機器位元組碼執行引擎虛擬機
- 淺談eval函式函式
- 淺談尤拉函式函式
- 淺談生成函式函式
- C++中抽象類、虛擬函式和純虛擬函式C++抽象函式
- C/C++ 結構體位元組對齊詳解C++結構體
- C語言:記憶體位元組對齊詳解C語言記憶體
- C/C++—— 記憶體位元組對齊規則C++記憶體
- C++:純虛擬函式與抽象類C++函式抽象
- 【C++筆記】虛擬函式(從虛擬函式概念來解析)C++筆記函式
- 淺談GPU虛擬化技術(四)-GPU分片虛擬化GPU
- 淺談GPU虛擬化技術(四)- GPU分片虛擬化GPU