C 物件記憶體模型探索

2021-09-11 03:21:01 字數 1640 閱讀 3063

實驗環境

ubuntu 18.04 64-bit gcc-7.3.0 g++-7.3.0,編譯使用-m32選項啟用32位環境

實驗步驟

1、不含有虛函式的基類,**如下:

#include class base 

private:

int i;

};int main()

執行結果:

kevin@kvm:~/study/temp$ g++ -g test.cc -m32

kevin@kvm:~/study/temp$ ./a.out

4

結論:在不含有虛函式的情況下,base型別例項的大小就是base類成員變數的大小。

2、給基類新增虛函式,**如下:

#include class base 

void print()

virtual int v_print_1()

virtual int v_print_2()

virtual ~base() {};

private:

int i;

};int main()

執行結果:

kevin@kvm:~/study/temp$ g++ -g test.cc -m32

kevin@kvm:~/study/temp$ ./a.out

8content of internal storage : 1000

結論:當基類本身定義了虛函式的時候(或繼承的父類有虛函式),為了繼承多型機制,編譯器將為該類新增乙個虛函式指標(__vfptr),虛函式指標指向虛函式表,虛函式表是乙個指向虛函式的指標的陣列(因此虛函式指標的型別為void ** __vfptr)。虛函式指標一般都放在物件記憶體布局的第乙個位置上,這是為了保證在多層繼承或多重繼承的情況下能以最高效率取到虛函式表。同時我們發現,雖然base類的資料成員 i 是 private的,我們也能夠通過物件的位址得到其儲存的值!

3、接下來,我們為base類新增靜態成員(static成員,包括靜態成員變數和靜態成員函式),**如下:

#include typedef void (*func)(void);

class base

void print()

virtual int v_print()

virtual int v_print_2()

static int getj()

virtual ~base() {};

private:

int i;

static int j;

};int base::j;

int main()

執行結果:

kevin@kvm:~/study/temp$ g++ -g test.cc -m32

kevin@kvm:~/study/temp$ ./a.out

sizeof(b) = 8

content of internal storage = 1000

結論:我們看到,靜態成員並不影響base類例項的大小!

探索C 物件模型

前兩篇部落格主要了解了多型和繼承的基礎,可是當我們在學習多型和繼承的時候,難免會碰到很多關於c 物件模型的問題,例如菱形繼承中的資料冗餘如何解決,虛基表是如何解決菱形繼承中資料冗餘問題等,這一篇部落格我們以c 中多型與繼承為基礎,探索c 物件模型。首先我們先來看看虛函式,虛函式就是在函式名前面加vi...

深度探索C 物件模型

傳世經典書叢 深度探索c 物件模型 美 stanley b.lippman 斯坦利 b.李普曼 著 侯捷 譯 isbn978 7 121 14952 8 2012年1月出版 定價 69.00元 16開 356頁 宣傳語 如果你是一位c 程式設計師,渴望對於底層知識獲得乙個完整的了解,那麼本書正適合你...

深度探索C 物件模型

傳世經典書叢 深度探索c 物件模型 美 stanley b.lippman 斯坦利 b.李普曼 著 侯捷譯 isbn978 7 121 14952 8 2012年1月出版 定價 69.00元 16開 356頁 宣傳語 如果你是一位c 程式設計師,渴望對於底層知識獲得乙個完整的了解,那麼本書正適合你 ...