標籤:
1 #include <iostream> 2 using namespace std; 3 class base1 4 { 5 int a; 6 double b; 7 char c; 8 }; 9 int main()10 {11 base1 b;12 return 1;13 }
vs輸出class布局方法:先選擇左側的C/C++->命令列,然後在其他選項這裡寫上/d1 reportAllClassLayout,它可以看到所有相關類的記憶體布局,如果寫上/d1 reportSingleClassLayoutXXX(XXX為類名),則只會打出指定類XXX的記憶體布局
base1記憶體布局
1 #include <iostream> 2 using namespace std; 3 class animal 4 { 5 protected: 6 int age; 7 public: 8 virtual void print_age(void) = 0; 9 };10 class dog:public animal11 {12 public:13 dog(){this->age = 2;}14 ~dog(){}15 virtual void print_age(void){cout<<"Wang,my age ="<< this->age<<endl;}16 };17 class cat:public animal18 {19 public:20 cat(){this->age = 1;}21 ~cat(){}22 virtual void print_age(void){cout<<"Miao,my age ="<< this->age<<endl;}23 };24 int main(void)25 {26 cat kitty;27 dog jd;28 animal * pa;29 int *p = (int*)(&kitty);30 int *q = (int*)(&jd);31 p[0] = q[0];32 cout<<p[1]<<endl;33 cout<<q[1]<<endl;34 pa = &kitty;35 pa ->print_age();36 system("pause");37 return 0;38 39 }
記憶體布局:
這個記憶體結構圖分成了兩個部分,上面是記憶體分布,下面是虛表,我們逐個看。VS所帶編譯器是把虛表指標放在了記憶體的開始處(0地址位移),然後再是成員變數;下面產生了虛表,緊跟在&[classname]_meta後面的0表示,這張虛表對應的虛指標在記憶體中的分布,下面列出了虛函數,左側的0是這個虛函數的序號,這裡只有一個虛函數,所以只有一項,如果有多個虛函數,會有序號為1,為2的虛函數列出來。
編譯器是在建構函式建立這個虛表指標以及虛表的。
那麼編譯器是如何利用虛表指標與虛表來實現多態的呢?是這樣的,當建立一個含有虛函數的父類的對象時,編譯器在物件建構時將虛表指標指向父類的虛函數;同樣,當建立子類的對象時,編譯器在建構函式裡將虛表指標(子類只有一個虛表指標,它來自父類)指向子類的虛表(這個虛表裡面的虛函數入口地址是子類的)。
輸出結果:
c++class 記憶體布局