關于虛函數(shù)表示例二小節(jié)存在的小問題。
從視頻中可以看出作者用的是 32 位的操作系統(tǒng),
因此在該小節(jié)中說將的東西在 32 位操作系統(tǒng)上都是對得上,
而在 64 位操作系統(tǒng)上就會有如下問題:
? ? 內(nèi)存對齊導致輸出不一樣,比如在該小節(jié)中為父類加了符合規(guī)定的虛函數(shù)(就是符合虛函數(shù)規(guī)則的函數(shù),如虛析構(gòu)函數(shù)、虛成員函數(shù)等等),父類輸出的結(jié)果為 8,這里毋庸置疑,而子類的結(jié)果卻為:16。這就會讓一些基礎比較弱的同學一頭霧水,WTH?為什么是 16 ,而不是 4 + 8 = 12 呢?這里面有幾個知識點:
????????1. 內(nèi)存對齊,因為指針的大小為 8 個字節(jié),而 int 類型的大小為 4 個字節(jié),則有 8 + 4 = 12,12 / 8 不等于一個整數(shù),不符合內(nèi)存對齊原理,因此為了符合內(nèi)存對齊的原理額外加了 4 個字節(jié), (12 + 4) / 8 = 2,因此這就是為什么輸出 16 的原因
????????2. 從上面第一個知識點可以猜測出,系統(tǒng)是把虛函數(shù)表指針放在了對象的第一個成員屬性上,為什么了。因為如果是把 m_iR 放在第一個位置上的話,則 (4 + 8) / 4 = 3 ,符合內(nèi)存對齊原理,那么輸出的應該為 12。
????????3.? 由上面兩個知識點可以知道另一個知識點,那就是我們在 q++ 之后輸出的值不是我們期望的 100,那是因為內(nèi)存對齊會填充不足的字節(jié),具體如下所示:
????????????void *p; (虛函數(shù)表指針 8 個字節(jié))
????????????int m_iR; (int 類型 4 個字節(jié))
????????????char pad[4]; (填充的 4 個字節(jié))
????????那么在我們執(zhí)行 q++ 時,指針的位置只是向后偏移了 4 個字節(jié)(int 類型占 4 個字節(jié)),而指針的大小占 8 個字節(jié)。
????????因此我們還需要再執(zhí)行一次 q++ ,這時 q 指針所指向的地址才是我們期望 m_iR 的地址,輸出才是我們期望的 100。
2018-10-11