在當前工程右鍵 --> 屬性:
先選擇左側的c/c++->命令列,然後在其他選項這裡寫上/d1 reportallclasslayout,它可以看到所有相關類的記憶體布局,如果寫上/d1 reportsingleclasslayout***(***為類名),則只會打出指定類***的記憶體布局。
成員變數是按照定義的順序來儲存的, 最先宣告的在最上邊, 然後依次儲存.
類物件的大小就是所有成員變數大小之和.
程式輸出:
sizeof(base_1) = 16
記憶體布局:
1> class base_1 size(16):
1> +---
1> 0 | base_1_1
1> 4 | base_1_2
1> 8 | base_1_3
測試**:
#include#includeusing namespace std;
class base_1
;int main()
可以看到物件的的大小等於成員屬性大小之和,普通的成員函式並不產生記憶體空間,也就不會對物件的布局造成任何影響,
那麼他就不可能會發生動態繫結,當呼叫乙個非虛函式時, 那麼呼叫的一定就是當前指標型別擁有的那個成員函式.
這種呼叫機制在編譯時期就確定下來了.
程式輸出:
sizeof(base_1) = 8
記憶體布局:
1> class base_1 size(8):
1> +---
1> 0 | base_1_1
1> 4 | base_1_2
1> +---
測試**:
#include#includeusing namespace std;
class base_1
};int main()
base1_1前面多了乙個變數 __vfptr(常說的虛函式表vtable指標),
其型別為void**, 這說明它是乙個void*指標(注意:不是陣列),是乙個指向陣列的指標.
虛函式指標__vfptr位於所有的成員變數之前定義.
程式輸出:
sizeof(base_1) = 12 (成員屬性 + 指向虛函式表的指標)
偽**:
void* __fun = ;
const void** __vfptr = &__fun[0];
記憶體布局:
1> class base_1 size(12):
1> +---
1> 0 |
1> 4 | base_1_1
1> 8 | base_1_2
1> +---
虛函式表:
1> base_1::$vftable@:
1> | &base_1_meta
1> | 0
1> 0 | &base_1::base_1_fun_1
測試**:
#include#includeusing namespace std;
class base_1
};int main()
通過這次可以看出__vfptr 只是乙個指向虛函式表的指標而已。
真正儲存物件中虛函式的是虛函式表,而這裡的虛函式指標只是提供乙個虛函式表的入口。
程式輸出:
sizeof(base_1) = 12 (成員屬性 + 指向虛函式表的指標)
偽**:
void* __fun = ;
const void** __vfptr = &__fun[0];
虛函式表:
1. 同乙個類的不同例項共用同乙份虛函式表, 它們都通過乙個所謂的虛函式表指標__vfptr(定義為void**型別)指向該虛函式表.
2. 它是編譯器在編譯時期為我們建立好的, 只存在乙份
3. 定義類物件時, 編譯器自動將類物件的__vfptr指向這個虛函式表
記憶體布局:
1> class base_1 size(12):
1> +---
1> 0 |
1> 4 | base_1_1
1> 8 | base_1_2
1> +---
虛函式表:
1> base_1::$vftable@:
1> | &base_1_meta
1> | 0
1> 0 | &base_1::base_1_fun_1
1> 1 | &base_1::base_1_fun_2
測試**:
#include#includeusing namespace std;
class base_1
virtual void base_1_fun_2() };
int main()
未完待續...
c++多型和物件的記憶體布局(二)
C 多型和物件的記憶體布局 二
程式輸出 sizeof base 1 12 成員屬性 指向虛函式表的指標 sizeof derive 1 20 base成員屬性 derive成員屬性 指向虛函式表的指標 base記憶體布局 1 class base 1 size 12 1 1 0 1 4 base1 1 1 8 base1 2 1...
c 物件的記憶體布局 一
本文主要討論c 對像的記憶體布局。對於乙個簡單的或者是複雜的c 類,他在記憶體裡到底是怎麼儲存的呢?每個類都有資料成員和介面,它們的儲存方式一樣嗎?虛函式為什麼會帶來儲存上的開銷?類的靜態成員和非靜態成員有什麼區別呢?本文將為你揭曉這些問題的答案。乙個空的類 class test int getx ...
C ,從RTTI聯絡多型物件記憶體布局
1 dynamic cast轉化,實現安全向下進行轉化,那麼實際上,根據vptr的指向,vtable中對應虛函式位址繫結的物件,來進行檢測以及轉化為實際的物件型別。2 typeid操作符,返回指標或者引用所指物件的實際型別。那麼關於dynamic cast,我們必須意識到,最關鍵的點在於虛表,這是多...