最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++對(duì)象的內(nèi)存結(jié)構(gòu)的實(shí)現(xiàn)

 更新時(shí)間:2026年01月29日 10:42:42   作者:bkspiderx  
本文主要介紹了C++對(duì)象的內(nèi)存結(jié)構(gòu)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在C++中,對(duì)象的內(nèi)存結(jié)構(gòu)并非由語言標(biāo)準(zhǔn)強(qiáng)制規(guī)定具體細(xì)節(jié)(不同編譯器可能有細(xì)微差異),但遵循一些通用規(guī)則。其內(nèi)存布局主要受成員變量、虛函數(shù)、繼承關(guān)系等因素影響,核心是為了高效存儲(chǔ)數(shù)據(jù)和支持面向?qū)ο蟮暮诵奶匦裕ㄈ绶庋b、繼承、多態(tài))。

一、基礎(chǔ)情況:無繼承、無虛函數(shù)的對(duì)象

對(duì)于一個(gè)僅包含非靜態(tài)成員變量的簡單類,對(duì)象的內(nèi)存結(jié)構(gòu)本質(zhì)上是成員變量的有序集合,不包含成員函數(shù)(成員函數(shù)存放在代碼區(qū),被所有對(duì)象共享)。

示例:

class Person {
private:
    int age;         // 4字節(jié)
    char gender;     // 1字節(jié)
    double height;   // 8字節(jié)
public:
    void print() {}  // 成員函數(shù),不占對(duì)象內(nèi)存
};

內(nèi)存結(jié)構(gòu):

對(duì)象的內(nèi)存中僅包含 age、genderheight 三個(gè)成員變量,按聲明順序排列,但會(huì)受到內(nèi)存對(duì)齊影響(編譯器為提高訪問效率,會(huì)在成員間插入填充字節(jié))。

假設(shè)按8字節(jié)對(duì)齊(常見編譯器默認(rèn)),內(nèi)存布局可能為:

偏移量  內(nèi)容
0-3     age(4字節(jié))
4-7     填充(4字節(jié),因gender僅1字節(jié),需對(duì)齊到下一個(gè)8字節(jié)邊界)
8-8     gender(1字節(jié))
9-15    填充(7字節(jié),為height的8字節(jié)對(duì)齊)
16-23   height(8字節(jié))

總大小:24字節(jié)(而非4+1+8=13字節(jié),填充字節(jié)是為了讓CPU更高效地訪問多字節(jié)類型)。

二、含靜態(tài)成員的對(duì)象

靜態(tài)成員(變量/函數(shù))屬于類級(jí)別的共享資源,不存儲(chǔ)在對(duì)象的內(nèi)存中,而是存放在全局?jǐn)?shù)據(jù)區(qū)(或靜態(tài)存儲(chǔ)區(qū)),所有對(duì)象共享同一份。

示例:

class Person {
private:
    int age;             // 非靜態(tài)成員,屬于對(duì)象
    static int count;    // 靜態(tài)成員,不屬于對(duì)象
public:
    static void incr() {} // 靜態(tài)函數(shù),不屬于對(duì)象
};
int Person::count = 0; // 靜態(tài)成員的定義

內(nèi)存結(jié)構(gòu):

對(duì)象的內(nèi)存中只包含非靜態(tài)成員age,countincr()存放在全局區(qū),與對(duì)象內(nèi)存無關(guān)。

三、含虛函數(shù)的對(duì)象(支持多態(tài))

當(dāng)類中包含虛函數(shù)(或繼承了虛函數(shù))時(shí),對(duì)象會(huì)額外包含一個(gè)虛函數(shù)表指針(vptr),用于支持多態(tài)特性。

核心概念:

  • 虛函數(shù)表(vtable):每個(gè)包含虛函數(shù)的類會(huì)有一個(gè)全局唯一的vtable,本質(zhì)是一個(gè)函數(shù)指針數(shù)組,存儲(chǔ)該類所有虛函數(shù)的地址。
  • 虛函數(shù)表指針(vptr):每個(gè)對(duì)象都會(huì)包含一個(gè)vptr(通常在對(duì)象內(nèi)存的開頭),指向所屬類的vtable。當(dāng)通過基類指針調(diào)用虛函數(shù)時(shí),編譯器會(huì)通過vptr找到vtable,再調(diào)用實(shí)際的函數(shù)(實(shí)現(xiàn)動(dòng)態(tài)綁定)。

示例:

class Animal {
public:
    virtual void eat() {} // 虛函數(shù)
    int weight;           // 成員變量
};

內(nèi)存結(jié)構(gòu):

偏移量  內(nèi)容
0-7     vptr(8字節(jié),指向Animal的vtable)
8-11    weight(4字節(jié),int類型)
  • vtable的內(nèi)容:[&Animal::eat](存儲(chǔ)eat()函數(shù)的地址)。
  • 若派生類重寫了虛函數(shù):
    class Cat : public Animal {
    public:
        void eat() override {} // 重寫虛函數(shù)
    };
    
    Cat類的vtable會(huì)替換為[&Cat::eat],Cat對(duì)象的vptr指向該vtable,實(shí)現(xiàn)“基類指針調(diào)用派生類函數(shù)”的多態(tài)。

四、繼承關(guān)系下的對(duì)象內(nèi)存結(jié)構(gòu)

繼承會(huì)導(dǎo)致派生類對(duì)象包含基類子對(duì)象(基類的成員變量+可能的vptr),再加上派生類自己的成員變量。

1. 單繼承(無虛函數(shù)覆蓋)

class Base {
public:
    int a;
};
class Derived : public Base {
public:
    int b;
};

Derived對(duì)象的內(nèi)存結(jié)構(gòu):

偏移量  內(nèi)容
0-3     a(基類成員)
4-7     b(派生類成員)

2. 單繼承(含虛函數(shù))

class Base {
public:
    virtual void f() {}
    int a;
};
class Derived : public Base {
public:
    virtual void g() {} // 新增虛函數(shù)
    int b;
};

Derived對(duì)象的內(nèi)存結(jié)構(gòu):

偏移量  內(nèi)容
0-7     vptr(指向Derived的vtable)
8-11    a(基類成員)
12-15   b(派生類成員)

Derived的vtable內(nèi)容:[&Base::f, &Derived::g](包含基類和派生類的虛函數(shù))。

3. 多繼承(最復(fù)雜的情況)

多繼承時(shí),派生類對(duì)象會(huì)包含所有基類的子對(duì)象,每個(gè)基類若有虛函數(shù),可能對(duì)應(yīng)一個(gè)vptr(導(dǎo)致對(duì)象內(nèi)存中存在多個(gè)vptr)。

示例:

class Base1 {
public:
    virtual void f() {}
    int a;
};
class Base2 {
public:
    virtual void g() {}
    int b;
};
class Derived : public Base1, public Base2 {
public:
    int c;
};

Derived對(duì)象的內(nèi)存結(jié)構(gòu)(可能):

偏移量  內(nèi)容
0-7      vptr1(指向Derived的vtable1,對(duì)應(yīng)Base1的虛函數(shù))
8-11     a(Base1的成員)
12-19    vptr2(指向Derived的vtable2,對(duì)應(yīng)Base2的虛函數(shù))
20-23    b(Base2的成員)
24-27    c(Derived的成員)

  • vtable1:[&Derived::f](繼承自Base1的虛函數(shù))
  • vtable2:[&Derived::g](繼承自Base2的虛函數(shù))

多繼承可能導(dǎo)致指針調(diào)整:當(dāng)用Base2*指向Derived對(duì)象時(shí),指針會(huì)自動(dòng)偏移到Base2子對(duì)象的起始位置(上例中偏移12字節(jié))。

4. 虛繼承(解決菱形繼承問題)

菱形繼承(兩個(gè)派生類繼承同一基類,再被一個(gè)類繼承)會(huì)導(dǎo)致基類成員在最終派生類中存在多份副本(數(shù)據(jù)冗余+二義性)。虛繼承通過讓基類子對(duì)象只存一份解決此問題。

示例(菱形繼承):

class A { public: int x; };
class B : virtual public A { public: int y; }; // 虛繼承A
class C : virtual public A { public: int z; }; // 虛繼承A
class D : public B, public C { public: int w; };

D對(duì)象的內(nèi)存結(jié)構(gòu)(簡化):

偏移量  內(nèi)容
0-7      vptr_B(B的虛表指針)
8-11     y(B的成員)
12-19    vptr_C(C的虛表指針)
20-23    z(C的成員)
24-27    w(D的成員)
28-31    x(A的成員,僅一份,被B和C共享)

  • 虛繼承通過在派生類中添加“虛基類指針”(或偏移量)定位共享的基類子對(duì)象,避免數(shù)據(jù)冗余。

總結(jié)

C++對(duì)象的內(nèi)存結(jié)構(gòu)核心由以下部分構(gòu)成(按影響優(yōu)先級(jí)):

  1. 非靜態(tài)成員變量:按聲明順序排列,受內(nèi)存對(duì)齊影響。
  2. 虛函數(shù)表指針(vptr):當(dāng)類有虛函數(shù)時(shí)存在,用于多態(tài),數(shù)量取決于繼承關(guān)系(多繼承可能有多個(gè)vptr)。
  3. 基類子對(duì)象:繼承時(shí)包含,順序與繼承聲明一致,虛繼承會(huì)優(yōu)化為共享副本。

靜態(tài)成員、成員函數(shù)不占用對(duì)象內(nèi)存,存放在全局區(qū)或代碼區(qū)。不同編譯器(如GCC、MSVC)在細(xì)節(jié)上(如vptr位置、對(duì)齊規(guī)則)可能有差異,但核心邏輯一致。

到此這篇關(guān)于C++對(duì)象的內(nèi)存結(jié)構(gòu)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++對(duì)象內(nèi)存結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    項(xiàng)目如果需要存儲(chǔ)很多日志記錄比如運(yùn)行日志,時(shí)間長了記錄數(shù)量非常多,數(shù)據(jù)庫體積不斷增大,對(duì)應(yīng)數(shù)據(jù)庫表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細(xì)介紹一下通用數(shù)據(jù)庫清理的實(shí)現(xiàn),需要的可以參考一下
    2022-02-02
  • 基于QT設(shè)計(jì)一個(gè)春聯(lián)自動(dòng)生成器

    基于QT設(shè)計(jì)一個(gè)春聯(lián)自動(dòng)生成器

    春節(jié)是中國最隆重的傳統(tǒng)節(jié)日,一到過年家家戶戶肯定是要貼春聯(lián);在春節(jié)前夕,會(huì)用大紅紙張,加上濃墨書寫祝福詞語。本文將利用Qt框架設(shè)計(jì)一個(gè)春聯(lián)自動(dòng)生成器,需要的可以參考一下
    2022-01-01
  • C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列)

    C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt數(shù)據(jù)庫應(yīng)用之通用數(shù)據(jù)庫同步

    Qt數(shù)據(jù)庫應(yīng)用之通用數(shù)據(jù)庫同步

    數(shù)據(jù)庫同步的主要功能是將本地的數(shù)據(jù)庫記錄同步到遠(yuǎn)程的數(shù)據(jù)庫。本文將利用Qt實(shí)現(xiàn)通用數(shù)據(jù)庫同步功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-03-03
  • C語言模擬實(shí)現(xiàn)strstr函數(shù)的示例代碼

    C語言模擬實(shí)現(xiàn)strstr函數(shù)的示例代碼

    strstr是C語言中的函數(shù),作用是返回字符串中首次出現(xiàn)子串的地址。本文將用C語言模擬實(shí)現(xiàn)strstr函數(shù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-07-07
  • 舉例講解C語言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法

    舉例講解C語言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法

    fork函數(shù)是Linux下一個(gè)近乎專有的C語言函數(shù),因?yàn)槭褂脮r(shí)需要調(diào)用unistd.h這個(gè)頭文件,這里我們就在Linux環(huán)境下舉例講解C語言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法,需要的朋友可以參考下
    2016-06-06
  • Linux下Select多路復(fù)用實(shí)現(xiàn)簡易聊天室示例

    Linux下Select多路復(fù)用實(shí)現(xiàn)簡易聊天室示例

    大家好,本篇文章主要講的是Linux下Select多路復(fù)用實(shí)現(xiàn)簡易聊天室示例,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • C++ STL之slist單向鏈表容器使用方式

    C++ STL之slist單向鏈表容器使用方式

    這篇文章主要介紹了C++ STL之slist單向鏈表容器使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • C語言中求解圖形的問題

    C語言中求解圖形的問題

    這篇文章主要介紹了C語言中求解圖形的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    實(shí)現(xiàn)順序表的插入,刪除,查找,輸出操作在C語言中經(jīng)常用到。下面小編給大家整理實(shí)現(xiàn)代碼,一起看下吧
    2016-08-08

最新評(píng)論

武山县| 德州市| 营山县| 昌图县| 镇巴县| 绥中县| 舞钢市| 元阳县| 东至县| 鹤岗市| 绩溪县| 广灵县| 九台市| 通化县| 当阳市| 安溪县| 霍城县| 平邑县| 嘉祥县| 抚州市| 林甸县| 舞阳县| 新和县| 武鸣县| 泰顺县| 古丈县| 铜梁县| 蕉岭县| 宝兴县| 旌德县| 双流县| 资溪县| 岳普湖县| 盐城市| 临湘市| 罗山县| 普宁市| 长宁区| 旌德县| 肥东县| 吉首市|