參考鏈接:C++ 虛基類表指針字節對齊模型
題目:
分別給出下面的類型Fruit和Apple的類型大小(即對象size),並通過畫出二者對象模型圖以及你的測試來解釋該size的構成原因。
聲明:編譯器是VC6.0
對象模型圖
黑色部分是我沒有找到什麼官方文檔來解釋,但是找到一邊博客,並且被CSDN的C++知識庫收錄,應該尤其權威性。
隱藏成員的加入不能影響在其後的成員的對齊
#include <iostream>
class Fruit
{
public:
void print()
{
printf("void print()\n");
}
virtual void process()
{
printf("void process()\n");
}
private:
int no;
double weight;
char key;
};
class Apple: public Fruit{
public:
void save() { }
virtual void process(){ printf("Apple\n"); }
private:
int size;
char type;
};
typedef void(*voidfunc)(void);
int main(int argc, char *argv[])
{
Fruit f;
void *p = (void*)&f;
voidfunc func;
func= (voidfunc)*((int*)*(int*)(&f)); //下面有講解
func();
printf("f.vptr = %p\n", &f);
printf("f.vptr_func1 = %p\n", *(int*)&f);
printf("func_process = %p\n", &Fruit::process);
printf("sizeof(Fruit) = %d\n", sizeof(Fruit));
printf("-----------------------------------------------------\n");
Apple a;
func= (voidfunc)*((int*)*(int*)(&a));
func();
printf("sizeof(Apple) = %d\n", sizeof(Apple));
return 0;
}
虛函數表指針位於指針的開始
func= (voidfunc)*((int*)*(int*)(&f));
&f ----> Fruit的地址
(int*)(&f)) ----> 強制轉成int* 地址
*(int*)(&f)) 獲取虛函數表的地址
(int*)*(int*)(&f) 強轉虛函數表的第一個元素的地址
*((int*)*(int*)(&f)) 獲取虛函數表中第一個元素的內容,也就是第一個虛函數的地址