日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++全局类对象_C++ 类在内存中的存储方式(一)

發(fā)布時間:2024/7/23 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++全局类对象_C++ 类在内存中的存储方式(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

說了這么久的 C++ 終于說到類了,還是從內(nèi)存出發(fā)來討論一下 C++ 的類在內(nèi)存中的存儲方式(之前寫過一篇內(nèi)存對齊的文章,類同樣在一定程度上遵循內(nèi)存對齊原則,不過比結構體復雜一下)

如有侵權,請聯(lián)系刪除,如有錯誤,歡迎大家指正,謝謝

0.空類

class Test {};Test t0; cout << sizeof(t0) << endl; // 運行結果:1

解釋:

  • 空類,沒有任何成員變量和成員函數(shù),編譯器是支持空類實例化對象的,對象必須要被分配內(nèi)存空間才有意義,這里編譯器默認分配了 1Byte 內(nèi)存空間(不同的編譯器可能不同)

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

解釋:

  • 這里的類的內(nèi)存對齊原則與前面寫的結構體的內(nèi)存對齊原則是一樣的(不太了解的可以移步我之前的《C/C++中內(nèi)存對齊問題的一些理解》查看)
  • 測試三中,32bit 目標平臺尋址空間是 4Byte(32bit),所以指針是 4Byte的;64bit 目標平臺尋址空間是 8Byte(64bit),所以指針是 8Byte
  • 另外,靜態(tài)成員變量是在編譯階段就在靜態(tài)區(qū)分配好內(nèi)存的,所以靜態(tài)成員變量的內(nèi)存大小不計入類空間(不太了解C++內(nèi)存分布的可以移步我之前寫的《C/C++程序的內(nèi)存分布》查看)

2.含有成員變量和成員函數(shù)的類

// ====== 測試一 ====== 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++中成員函數(shù)和非成員函數(shù)都是存放在代碼區(qū)的,故類中一般成員函數(shù)、友元函數(shù),內(nèi)聯(lián)函數(shù)還是靜態(tài)成員函數(shù)都不計入類的內(nèi)存空間,測試一和測試二對比可證明這一點
  • 測試三中,因出現(xiàn)了虛函數(shù),故類要維護一個指向虛函數(shù)表的指針,分別在 x86目標平臺和x64目標平臺下編譯運行的結果可證明這一點

總結

  • C++編譯系統(tǒng)中,數(shù)據(jù)和函數(shù)是分開存放的(函數(shù)放在代碼區(qū);數(shù)據(jù)主要放在棧區(qū)和堆區(qū),靜態(tài)/全局區(qū)以及文字常量區(qū)也有),實例化不同對象時,只給數(shù)據(jù)分配空間,各個對象調(diào)用函數(shù)時都都跳轉到(內(nèi)聯(lián)函數(shù)例外)找到函數(shù)在代碼區(qū)的入口執(zhí)行,可以節(jié)省拷貝多份代碼的空間
  • 類的靜態(tài)成員變量編譯時被分配到靜態(tài)/全局區(qū),因此靜態(tài)成員變量是屬于類的,所有對象共用一份,不計入類的內(nèi)存空間
  • 靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)都是存放在代碼區(qū)的,是屬于類的,類可以直接調(diào)用靜態(tài)成員函數(shù),不可以直接調(diào)用非靜態(tài)成員函數(shù),兩者主要的區(qū)別是有無this指針,更加詳細的解釋后面專門寫一篇文章
  • 內(nèi)聯(lián)函數(shù)(聲明和定義都要加inline)也是存放在代碼區(qū),內(nèi)聯(lián)函數(shù)在被調(diào)用時,編譯器會用內(nèi)聯(lián)函數(shù)的代碼替換掉函數(shù),避免了函數(shù)跳轉和保護現(xiàn)場的開銷(實際上到底替不替換還要由編譯器決定,即使聲明為內(nèi)聯(lián)函數(shù)也有可能不替換,未聲明成內(nèi)聯(lián)函數(shù)也有可能被編譯器替換到調(diào)用位置,主要由編譯器決定),更詳細的介紹后面也會專門寫一篇文章

參考文章:

[1] C++成員函數(shù)在內(nèi)存中的存儲方式

[2] C++類的實例化對象的大小之sizeof() (該文章有一處錯誤,“如果是指針,則無論指針指向的是什么數(shù)據(jù)類型,都占4個字節(jié)的存儲空間”,在x86目標平臺下4Byte,在x64目標平臺下8Byte)

如果未特殊說明,以上測試均是在win10 vs2017 64bit編譯器下進行的

總結

以上是生活随笔為你收集整理的c++全局类对象_C++ 类在内存中的存储方式(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。