天天看點

C++類的大小

一個空類class A{};的大小為什麼是1,因為如果不是1,當定義這個類的對象數組時候A objects[5]; objects[0]和objects[1]就在同一個位址處,就無法區分。

單繼承

C++類的大小
C++類的大小

vs和gcc下

執行結果:A's size is 8

              B's size is 8

說明:有虛函數的類有個virtual table(虛函數表),裡面包含了類的所有虛函數,類中有個virtual table pointers,通常成為vptr指向這個virtual table,占用4個位元組的大小。成員類B public繼承于A,類B的虛函數表裡實際上有兩個虛函數A::aa()和B::bb(),類B的大小等于char k[3]的大小加上一個指向虛函數表指針vptr的大小,考慮記憶體對齊為8。

C++類的大小
C++類的大小

說明:類B看上去沒有虛函數,但實際上它有,隻是沒有重寫,因為public繼承,是以有從A繼承過來的虛函數A::aa(),實際上類A和類B的虛函數表裡的函數都是A::aa()。

C++類的大小
C++類的大小

說明:一個類裡若有虛函數,無論有多少個虛函數都隻有一個指向虛表的指針,虛表中的每一個表項儲存着一個虛函數的入口位址。當調用虛函數時,先找到虛表中它對應的表項,找到入口位址再執行。對于直接單繼承,無論類B中有無虛函數,由于它繼承了類A,且類A裡含有虛函數,是以如果類B有虛函數,那麼它和類A的是在同一個屬于類B的虛表裡,這張虛表的虛函數為A::aa()、A::aa2()、B::bb()、B::bb2()。注意:類A裡的私有成員在類B裡仍占有記憶體。

多繼承

C++類的大小
C++類的大小

          B's size is 4

          B's size is 12

說明:類A和B的大小就不解釋了,參照上面。類C多重繼承于A和B(有虛函數覆寫),那麼類C的大小是多少?先看成員變量,有一個繼承A的char k[3]。再看虛函數,類C的中虛函數是怎麼分布的?先有一個虛函數表,裡面有繼承于類A的虛函數和C自己的虛函數(C::aa(), A::aa2(), C::cc()),如果C沒有重寫aa(),那麼第一個虛函數就是A::aa(),接着有第二張虛函數表是繼承包含類B的虛函數B::bb()、B::bb2()(類C沒有重寫B的虛函數)。總的大小就是2張虛表的大小(也即兩個虛函數指針的大小)8位元組加上3位元組的k[3],考慮記憶體對齊,就是12位元組。

虛繼承

C++類的大小
C++類的大小

              B's size is 12

說明:類B裡包含,繼承的char k[3],繼承的虛函數,類B的虛函數表裡有A::aa(),因為是虛繼承,還有一個指向父類的指針,該指針為指向虛基類的指針(Pointer to virtual base class)。考慮記憶體對齊,總大小為12。

C++類的大小
C++類的大小

VS執行結果:A's size is 8

                  B's size is 16

gcc執行結果:A's size is 8

                  B's size is 12

說明:對于虛繼承,類B虛繼承類A時,首先要通過加入一個指針來指向父類A,該指針被稱為虛基類指針。然後包含從父類繼承過來的3個char,再加上一個虛函數指針。考慮記憶體對齊,在gcc下結果是4+4+4=12。在VS下,結果是16,why?這一題和上一題差別隻是在類B中添加了一個虛函數,但是兩個題目中類B都有虛函數表。在VS下調試檢視彙編代碼,發現多出來的4位元組什麼也沒有。

    本文轉自阿凡盧部落格園部落格,原文連結:http://www.cnblogs.com/luxiaoxun/archive/2012/09/01/2666395.html,如需轉載請自行聯系原作者

繼續閱讀