c++全局类对象_C++ 类在内存中的存储方式(一)
生活随笔
收集整理的這篇文章主要介紹了
c++全局类对象_C++ 类在内存中的存储方式(一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
說了這么久的 C++ 終于說到類了,還是從內存出發來討論一下 C++ 的類在內存中的存儲方式(之前寫過一篇內存對齊的文章,類同樣在一定程度上遵循內存對齊原則,不過比結構體復雜一下)
如有侵權,請聯系刪除,如有錯誤,歡迎大家指正,謝謝
0.空類
class Test {};Test t0; cout << sizeof(t0) << endl; // 運行結果:1解釋:
- 空類,沒有任何成員變量和成員函數,編譯器是支持空類實例化對象的,對象必須要被分配內存空間才有意義,這里編譯器默認分配了 1Byte 內存空間(不同的編譯器可能不同)
1. 含有成員變量的類
// ====== 測試一 ====== class Test { private:int i;char c;double d; };Test t11; cout << sizeof(t11) << endl; // 運行結果:16// ====== 測試二 ====== class A{};class Test { private:int i;char c;double d;A a; };Test t12; cout << sizeof(t12) << endl; // 運行結果:24// ====== 測試三 ====== class A { private:double dd;int ii;int* pp; };class Test { private:int i;A a;double d;char* p; };Test t13; cout << sizeof(t13) << endl; // x86目標平臺運行結果:40;x64目標平臺下運行結果:48解釋:
- 這里的類的內存對齊原則與前面寫的結構體的內存對齊原則是一樣的(不太了解的可以移步我之前的《C/C++中內存對齊問題的一些理解》查看)
- 測試三中,32bit 目標平臺尋址空間是 4Byte(32bit),所以指針是 4Byte的;64bit 目標平臺尋址空間是 8Byte(64bit),所以指針是 8Byte
- 另外,靜態成員變量是在編譯階段就在靜態區分配好內存的,所以靜態成員變量的內存大小不計入類空間(不太了解C++內存分布的可以移步我之前寫的《C/C++程序的內存分布》查看)
2.含有成員變量和成員函數的類
// ====== 測試一 ====== class Test { private:int n;char c;short s; };Test t21; cout << sizeof(t21) << endl; // 運行結果:8// ====== 測試二 ====== class Test { public:Test() {}int func0() {return n;}friend int func1();int func2() const {return s;}inline void func3() {cout << "inline function" << endl;}static void func4() {cout << "static function" << endl;}~Test() {}private:int n;char c;short s; };int func1() {Test t;return t.c; }Test t22; cout << sizeof(t22) << endl; // 運行結果:8// ====== 測試三 ====== class Test { public:Test() {}int func0() {return n;}friend int func1();int func2() const {return s;}inline void func3() {cout << "inline function" << endl;}static void func4() {cout << "static function" << endl;}virtual void func5() {cout << "virtual function" << endl;}~Test() {}private:int n;char c;short s; };int func1() {Test t;return t.c; }Test t23; cout << sizeof(t23) << endl; // x86目標平臺運行結果:12;x64目標平臺下運行結果:16解釋:
- 因 C++中成員函數和非成員函數都是存放在代碼區的,故類中一般成員函數、友元函數,內聯函數還是靜態成員函數都不計入類的內存空間,測試一和測試二對比可證明這一點
- 測試三中,因出現了虛函數,故類要維護一個指向虛函數表的指針,分別在 x86目標平臺和x64目標平臺下編譯運行的結果可證明這一點
總結
- C++編譯系統中,數據和函數是分開存放的(函數放在代碼區;數據主要放在棧區和堆區,靜態/全局區以及文字常量區也有),實例化不同對象時,只給數據分配空間,各個對象調用函數時都都跳轉到(內聯函數例外)找到函數在代碼區的入口執行,可以節省拷貝多份代碼的空間
- 類的靜態成員變量編譯時被分配到靜態/全局區,因此靜態成員變量是屬于類的,所有對象共用一份,不計入類的內存空間
- 靜態成員函數和非靜態成員函數都是存放在代碼區的,是屬于類的,類可以直接調用靜態成員函數,不可以直接調用非靜態成員函數,兩者主要的區別是有無this指針,更加詳細的解釋后面專門寫一篇文章
- 內聯函數(聲明和定義都要加inline)也是存放在代碼區,內聯函數在被調用時,編譯器會用內聯函數的代碼替換掉函數,避免了函數跳轉和保護現場的開銷(實際上到底替不替換還要由編譯器決定,即使聲明為內聯函數也有可能不替換,未聲明成內聯函數也有可能被編譯器替換到調用位置,主要由編譯器決定),更詳細的介紹后面也會專門寫一篇文章
參考文章:
[1] C++成員函數在內存中的存儲方式
[2] C++類的實例化對象的大小之sizeof() (該文章有一處錯誤,“如果是指針,則無論指針指向的是什么數據類型,都占4個字節的存儲空間”,在x86目標平臺下4Byte,在x64目標平臺下8Byte)
如果未特殊說明,以上測試均是在win10 vs2017 64bit編譯器下進行的
總結
以上是生活随笔為你收集整理的c++全局类对象_C++ 类在内存中的存储方式(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python从小到大的顺序输出_「小白专
- 下一篇: android 模糊读取文件名_Andr