欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入解析C++ Data Member內存布局

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

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

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

復制代碼 代碼如下:

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的每個實例中可能有不同的值,當然屬于Point實例的一部分,如果把maxCount定義成static,那它就不不是Point實例的一部分了,如果定義成static  const int maxCount=1;則maxCount分配在.data段中,如果沒有初始化則分配在.bss段中,反正跟Point的實例無關,count分配在.bss段中,minCount分配在.rdata段中,總之count,maxCount,minCount在編譯連接完成之后,內存(虛擬地址)就分配好了,在程序加載的時候,會把他們的虛擬地址對應上實際的物理地址。

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

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

復制代碼 代碼如下:

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é)對齊



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

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

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

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

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

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

相關文章

  • 淺談C++函數(shù)聲明后面加throw()的作用(必看)

    淺談C++函數(shù)聲明后面加throw()的作用(必看)

    下面小編就為大家?guī)硪黄獪\談C++函數(shù)聲明后面加throw()的作用(必看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C語言編程之預處理過程與define及條件編譯

    C語言編程之預處理過程與define及條件編譯

    這篇文章主要為大家介紹了C語言編程之預處理過程與define及條件編譯,文中通過圖文及示例代碼方式作了詳細的解釋,有需要的朋友可以借鑒參考下
    2021-09-09
  • 用C語言簡單實現(xiàn)掃雷小游戲

    用C語言簡單實現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細介紹了用C語言簡單實現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++淺析虛函數(shù)使用方法

    C++淺析虛函數(shù)使用方法

    對C++了解的人都應該知道虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)來實現(xiàn)的。簡稱為V-Table。本文就將詳細講講虛函數(shù)表的原理與使用,需要的可以參考一下
    2022-08-08
  • 利用Matlab實現(xiàn)圖像亮度分布統(tǒng)計圖

    利用Matlab實現(xiàn)圖像亮度分布統(tǒng)計圖

    這篇文章主要介紹了如何利用Matlab實現(xiàn)圖像亮度分布統(tǒng)計圖的繪制,文中的示例代碼講解詳細,對我們學習Matlab有一定的幫助,感興趣的可以了解一下
    2022-05-05
  • C++中stack的pop()函數(shù)返回值解析

    C++中stack的pop()函數(shù)返回值解析

    這篇文章主要介紹了C++中stack的pop()函數(shù)返回值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C語言分支循環(huán)其嵌套語句的使用

    C語言分支循環(huán)其嵌套語句的使用

    本文主要介紹了switch 嵌套和循環(huán)嵌套,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語言中字符串的存儲方法

    C語言中字符串的存儲方法

    這篇文章主要為大家詳細介紹了C語言中字符串的存儲方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C++使用OpenCV實現(xiàn)證件照藍底換成白底功能(或其他顏色如紅色)詳解

    C++使用OpenCV實現(xiàn)證件照藍底換成白底功能(或其他顏色如紅色)詳解

    這篇文章主要介紹了C++使用OpenCV實現(xiàn)證件照藍底換成白底功能(或其他顏色如紅色),結合實例形式詳細分析了OpenCV顏色轉換相關操作原理與實現(xiàn)技巧,需要的朋友可以參考下
    2019-12-12
  • OpenCV 顏色追蹤的示例代碼

    OpenCV 顏色追蹤的示例代碼

    這篇文章主要介紹了OpenCV 顏色追蹤的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01

最新評論