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

深入解析C++ Data Member內(nèi)存布局

 更新時(shí)間:2013年07月09日 15:08:42   投稿:jingxian  
本篇文章是對C++中的Data Member內(nèi)存布局進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

如果一個(gè)類只定義了類名,沒定義任何方法和字段,如class A{};那么class A的每個(gè)實(shí)例占用1個(gè)字節(jié)的內(nèi)存,編譯器會(huì)會(huì)在這個(gè)其實(shí)例中安插一個(gè)char,以保證每個(gè)A實(shí)例在內(nèi)存中有唯一的地址,如A a,b;&a!=&b。如果一個(gè)直接或是間接的繼承(不是虛繼承)了多個(gè)類,如果這個(gè)類及其父類像A一樣沒有方法沒有字段,那么這個(gè)類的每個(gè)實(shí)例的大小都是1字節(jié),如果有虛繼承,那就不是1字節(jié)了,每虛繼承一個(gè)類,這個(gè)類的實(shí)例就會(huì)多一個(gè)指向被虛繼承父類的指針。還有一點(diǎn)值得說明的就是像A這樣的類,編譯器不一定會(huì)產(chǎn)生傳說中的那6個(gè)方法,這些方法只會(huì)在需要的時(shí)候產(chǎn)生,如class  A沒有被任何地方使用那這些方法編譯器就沒有必要產(chǎn)生,如果這個(gè)類實(shí)例化了,那么會(huì)產(chǎn)生default constructor,而destructor則不一定產(chǎn)生。

如果一個(gè)類中有static data member,nonstatic data member,還有const data member,enum,那么它的內(nèi)存布局會(huì)是什么樣的呢,看下面簡單的類Point:

復(fù)制代碼 代碼如下:

class Point
{
public:
    Point():maxCount(10){}
private:
    int X;
    static int count;
    int Y;
    const int maxCount ;
    enum{
        minCount=2
    };
};

Sizeof(Point)=12,為什么占12字節(jié)呢,我相信很多人都知道是哪幾個(gè)成員變量占用的,就是X,Y,maxCount,maxCount作為常量字段,但在Point的每個(gè)實(shí)例中可能有不同的值,當(dāng)然屬于Point實(shí)例的一部分,如果把maxCount定義成static,那它就不不是Point實(shí)例的一部分了,如果定義成static  const int maxCount=1;則maxCount分配在.data段中,如果沒有初始化則分配在.bss段中,反正跟Point的實(shí)例無關(guān),count分配在.bss段中,minCount分配在.rdata段中,總之count,maxCount,minCount在編譯連接完成之后,內(nèi)存(虛擬地址)就分配好了,在程序加載的時(shí)候,會(huì)把他們的虛擬地址對應(yīng)上實(shí)際的物理地址。

Data member的內(nèi)存布局:nonstatic data member在class object中的順序和其申明的順序一樣,static data  member和const member不在class object中因?yàn)樗麄冎挥幸环?,被class object共享,所以static data member和const data member,枚舉并不會(huì)響應(yīng)class object的大小。關(guān)于段的信息,我覺得是每個(gè)C/C++程序員必須知道的。而Point每次實(shí)例化的時(shí)候則只需要分配X,Y,maxCount需要的內(nèi)存。

每個(gè)類的data member在內(nèi)存中應(yīng)該是連續(xù)的,如果出現(xiàn)數(shù)據(jù)對齊的情況,可能中間會(huì)有空白地帶。請看下面幾個(gè)類:

復(fù)制代碼 代碼如下:

class AA
{
protected:
    int X;
    char a;
};

class BB:public AA
{
protected:
    char b;
};

class CC:public BB
{
protected:
    char c;
};


Sizeof(AA)=8//對齊3字節(jié)
Sizeof(BB)=12//兩個(gè)3字節(jié)對齊
Sizeof(CC)=16//編譯器用了3個(gè)3字節(jié)對齊



編譯器為什么的在class CC中加3個(gè)3字節(jié)對齊呢,這樣每個(gè)CC的實(shí)例就大了9字節(jié)。如果編譯器不加這9字節(jié)的空白,那么CC的每個(gè)實(shí)例就是8字節(jié),前面的X占4字節(jié),后面的a,b,c占3字節(jié),加1字節(jié)的空白對齊,剛好8字節(jié),沒有誰很傻很天真的以為最好是占7字節(jié)吧。

如果CC占用8字節(jié)內(nèi)存,同樣的AA,BB都是8字節(jié)的內(nèi)存,這樣的話,如果把一個(gè)指向AA實(shí)例的指針賦給一個(gè)指向CC實(shí)例的指針,那么就會(huì)把AA中的8字節(jié)直接蓋到CC的8字節(jié)上,結(jié)果CC實(shí)例中的b,c都被賦上了不是我們想要的值,這很可能會(huì)導(dǎo)致你的程序出問題。

父類的data member會(huì)在子類的實(shí)例中有完整的一份,這樣在有繼承關(guān)系的類之間進(jìn)行類型轉(zhuǎn)換,就只用簡單的修改指針的指向。

Data Member的存取。對一個(gè)data member的存取,編譯器把對象實(shí)例的起始地址加上data member的偏移量。如CC c;

c.X=1;相當(dāng)于&c+(&CC::X-1),減一其實(shí)是為了區(qū)分是指向object的指針還是指向data member的指針,指向data member的要減一。每一個(gè)data member的偏移量在編譯的時(shí)候是知道的,根據(jù)成員變量的類型和內(nèi)存對齊,存在virtual繼承或是虛方法的情況編譯器會(huì)自動(dòng)加上一些輔助的指針,如指向虛方法的指針,指向虛繼承父類的指針等。

在data member的存取效率上,struct member 、class member、單一繼承或是多重繼承的情況下效率都是一樣的,因?yàn)樗麄兊拇鎯?chǔ)其實(shí)都是&obj+(&class.datamember-1)。在虛繼承的情況下,可能會(huì)影響存儲(chǔ)性能,如通過一個(gè)指針來存取一個(gè)指向虛繼承而來的data member,那么性能會(huì)有影響,因?yàn)樵谔摾^承的時(shí)候,在編譯的時(shí)候還不能確定這個(gè)data member是來自子類還是父類,只有在運(yùn)行的時(shí)候才能推斷出來,其實(shí)就是多了一步指針的操作,在虛繼承中,如果是通過對象實(shí)例來操作虛繼承而來的data member,則不會(huì)有任何性能問題,因?yàn)椴淮嬖谑裁炊鄳B(tài)性,所有東西在編譯的時(shí)候內(nèi)存地址都確定了。

虛繼承還是虛方法為了實(shí)現(xiàn)多態(tài)一樣,多了一步,如果不需要多態(tài),而是通過對象實(shí)例調(diào)用相關(guān)的方法就不會(huì)有性能問題。

相關(guān)文章

  • C語言實(shí)現(xiàn)小型工資管理系統(tǒng)

    C語言實(shí)現(xiàn)小型工資管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)小型工資管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 老生常談C++中實(shí)參形參的傳遞問題

    老生常談C++中實(shí)參形參的傳遞問題

    下面小編就為大家?guī)硪黄仙U凜++中實(shí)參形參的傳遞問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • 淺析C語言位域和位段

    淺析C語言位域和位段

    以下是對C語言中的位域和位段進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    fgetc() 和 fputc() 函數(shù)每次只能讀寫一個(gè)字符,速度較慢,實(shí)際開發(fā)中往往是每次讀寫一個(gè)字符串或者一個(gè)數(shù)據(jù)塊,這樣能明顯提高效率,這篇文章主要給大家介紹了關(guān)于C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • C++類中隱藏的幾個(gè)默認(rèn)函數(shù)你知道嗎

    C++類中隱藏的幾個(gè)默認(rèn)函數(shù)你知道嗎

    這篇文章主要為大家詳細(xì)介紹了C++類中隱藏的幾個(gè)默認(rèn)函數(shù),使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 詳解C++中mutable的用法

    詳解C++中mutable的用法

    這篇文章主要介紹了詳解C++中mutable的用法,幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-08-08
  • 使用C語言實(shí)現(xiàn)三子棋小游戲

    使用C語言實(shí)現(xiàn)三子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了使用C語言實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 《C++ primer plus》讀書筆記(一)

    《C++ primer plus》讀書筆記(一)

    本讀書筆記是C++ primer plus(第六版)前3章的學(xué)習(xí)筆記。非常的淺顯易懂,復(fù)習(xí)C++基礎(chǔ)知識(shí)的可以瞄瞄。
    2014-10-10
  • 淺析VSCode tasks.json中的各種替換變量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等

    淺析VSCode tasks.json中的各種替換變量的意思 ${workspaceFolder} ${file} ${

    這篇文章主要介紹了關(guān)于VSCode tasks.json中的各種替換變量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • C語言實(shí)現(xiàn)圖書管理系統(tǒng)

    C語言實(shí)現(xiàn)圖書管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論

樟树市| 黎川县| 天柱县| 遵义县| 明溪县| 尼勒克县| 石首市| 怀安县| 景谷| 和静县| 安福县| 方正县| 洪江市| 安仁县| 涞源县| 汤阴县| 泽州县| 隆尧县| 祁门县| 夏河县| 垣曲县| 房产| 根河市| 南岸区| 深水埗区| 顺昌县| 玉屏| 沈阳市| 当涂县| 临潭县| 兴业县| 安丘市| 江城| 浦东新区| 上饶县| 武定县| 调兵山市| 晋城| 方山县| 九台市| 葵青区|