一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - 深入解析C++ Data Member內(nèi)存布局

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

2020-12-16 14:42C++教程網(wǎng) C/C++

本篇文章是對C++中的Data Member內(nèi)存布局進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

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

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

 

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

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

復(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//兩個3字節(jié)對齊
Sizeof(CC)=16//編譯器“無恥”的用了3個3字節(jié)對齊

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

編譯器為什么要無恥的在class CC中加3個3字節(jié)對齊呢,這樣每個CC的實例就大了9字節(jié)。如果編譯器不加這9字節(jié)的空白,那么CC的每個實例就是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)存,這樣的話,如果把一個指向AA實例的指針賦給一個指向CC實例的指針,那么就會把AA中的8字節(jié)直接蓋到CC的8字節(jié)上,結(jié)果CC實例中的b,c都被賦上了不是我們想要的值,這很可能會導(dǎo)致你的程序出問題。

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

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

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

在data member的存取效率上,struct member 、class member、單一繼承或是多重繼承的情況下效率都是一樣的,因為他們的存儲其實都是&obj+(&class.datamember-1)。在虛繼承的情況下,可能會影響存儲性能,如通過一個指針來存取一個指向虛繼承而來的data member,那么性能會有影響,因為在虛繼承的時候,在編譯的時候還不能確定這個data member是來自子類還是父類,只有在運(yùn)行的時候才能推斷出來,其實就是多了一步指針的操作,在虛繼承中,如果是通過對象實例來操作虛繼承而來的data member,則不會有任何性能問題,因為不存在什么多態(tài)性,所有東西在編譯的時候內(nèi)存地址都確定了。

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

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++C語言實現(xiàn)電腦關(guān)機(jī)程序

    C語言實現(xiàn)電腦關(guān)機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進(jìn)行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
主站蜘蛛池模板: 果冻传媒新在线观看免费 | 国产成人综合手机在线播放 | 午夜爱爱爱爱爽爽爽视频网站 | 国产精品99久久免费观看 | 精品无码国产污污污免费网站2 | 九九精品免视频国产成人 | 国内自拍网红在线综合 | 日韩在线视频免费不卡一区 | 91制片厂官网 | 日本高清中文字幕一区二区三区 | 亚洲一区二区三区91 | 猫咪社区免费资源在线观看 | 欧美久久久久久久一区二区三区 | 91混血大战上海双胞胎 | 二区三区在线观看 | 天天色国产 | 2018成年动漫在线观看 | 亚洲国产精品综合福利专区 | 欧美精品一区二区三区免费播放 | 女同学用白丝脚玩我的故事 | 精品久久久久久久国产潘金莲 | 精品一区二区三区免费视频 | 放荡护士玩3p口述 | 免费网址视频在线看 | 欧美日韩va | 天堂网在线.www天堂在线视频 | 欧美一卡二卡科技有限公司 | 国产高清不卡视频在线播放 | 国产精品久久久久影视不卡 | 亚洲第一区二区快射影院 | 特级毛片免费观看视频 | 精品9e精品视频在线观看 | 久久伊人中文字幕有码 | 成人亚洲欧美日韩中文字幕 | 人人爽人人射 | 亚洲精品视频在线免费 | 男女做污事| 午夜办公室 | 五月色婷婷网在线观看 | 日韩播放| 久久精品嫩草影院免费看 |