C++對象模型是比較重要的一個知識點,學習C++對象的內存模型,就可以明白C++中的多態原理、類的初始化順序問題、類的大小問題等。
C++對象中包括以下內容:
以下是一個對象的定義:
class Base { static int b_s; public: void function() { } virtual void v_function() { cout << "Base v_function()" << endl; } private: int b_a; int b_b; };
假如使用Base類作為測試,那Base類在內存中占用幾個字節呢?
Windows7 vs2013測試結果:
CentOS7 64位 vim測試結果:
通過以上兩個測試結果圖分析可知,一個類的占用內存大小由以下成員決定:
測試代碼如下:
#include <iostream> using namespace std; class Base { static int b_s; public: void function() { } virtual void v_function() { cout << "Base v_function()" << endl; } int b_a; int b_b; }; int Base::b_s = 0; int main(int argc, char **argv) { Base base; base.b_a = 1; base.b_b = 2; cout << "size: " << sizeof(base) << endl; int *p = (int *) &base; cout << *p << endl; p++; cout << *p << endl; p++; cout << *p << endl; system("pause"); return 0; }
輸出結果為:
輸出結果中的1和2為類中b_a和b_b成員的值,11459700表示一個地址,改地址包含有虛表的信息。Base類的大致內存布局如下:
class Empty { }; int main(int argc, char **argv) { Empty empty; Empty emptys[10]; cout << sizeof(empty) << endl; cout << sizeof(emptys) << endl; system("pause"); return 0; }
輸出結果為:
空類中什麼都沒有,但是定義一個空類類型的變量(實例),每個實例在內存中都有一個獨一無二的地址,為了達到這個目的,編譯器往往會給一個空類隱含的加一個字節,這樣空類在實例化後在內存得到了獨一無二的地址。
(1)從太空角度看類初始化順序
基類初始化 – 子類初始化
(2)從空中角度看類初始化順序
基類靜態成員 – 子類靜態成員 – 基類成員變量 –基類構造函數 – 子類成員變量 – 子類構造函數
(3)站到地上看類初始化順序
基類靜態成員 – 子類靜態成員 – (設置v_ptr/基類成員變量 ) –基類構造函數 – (設置v_ptr/子類成員變量) – 子類構造函數
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2016-10/135765p2.htm