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

C++對象內(nèi)存分布詳解(包括字節(jié)對齊和虛函數(shù)表)

 更新時間:2016年12月25日 10:56:35   投稿:jingxian  
下面小編就為大家?guī)硪黄狢++對象內(nèi)存分布詳解(包括字節(jié)對齊和虛函數(shù)表)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、C++對象的內(nèi)存分布和虛函數(shù)表:

C++對象的內(nèi)存分布和虛函數(shù)表注意,對象中保存的是虛函數(shù)表指針,而不是虛函數(shù)表,虛函數(shù)表在編譯階段就已經(jīng)生成,同類的不同對象中的虛函數(shù)指針指向同一個虛函數(shù)表,不同類對象的虛函數(shù)指針指向不同虛函數(shù)表。

2、何時進行動態(tài)綁定:

(1)每個類對象在被構(gòu)造時不用去關(guān)心是否有其他類從自己派生,也不需要關(guān)心自己是否從其他類派生,只要按照一個統(tǒng)一的流程:在自身的構(gòu)造函數(shù)執(zhí)行之前把自己所屬類(即當前構(gòu)造函數(shù)所屬的類)的虛函數(shù)表的地址綁定到當前對象上(一般是保存在對象內(nèi)存空間中的前4個字節(jié))。因為對象的構(gòu)造是從最基類部分(比如A<-B<-C,A是最基類,C是最派生類)開始構(gòu)造,一層一層往外構(gòu)造中間類(B),最后構(gòu)造的是最派生類(C),所以最終對象上綁定的就自然而然就是最派生類的虛函數(shù)表。

(2)析構(gòu)函數(shù)的調(diào)用跟構(gòu)造函數(shù)的調(diào)用順序是相反的,它從最派生類的析構(gòu)函數(shù)開始的。也就是說當基類的析構(gòu)函數(shù)執(zhí)行時,派生類的析構(gòu)函數(shù)已經(jīng)執(zhí)行過,派生類中的成員數(shù)據(jù)被認為已經(jīng)無效(包括派生類對象中的虛表指針)。假設(shè)基類中虛函數(shù)調(diào)用能調(diào)用得到派生類的虛函數(shù),那么派生類的虛函數(shù)將訪問一些已經(jīng)“無效”的數(shù)據(jù),所帶來的問題和訪問一些未初始化的數(shù)據(jù)一樣。而同樣,我們可以認為在析構(gòu)的過程中,虛函數(shù)表也是在不斷變化的,不斷解綁定。

因此,在基類構(gòu)造函數(shù)或者析構(gòu)函數(shù)中調(diào)用虛函數(shù),并不會綁定到派生類的實現(xiàn)上,因為在這兩個函數(shù)執(zhí)行時虛函數(shù)表指針指向的是基類的虛函數(shù)表。

3、C++中類的大小:

由 1 可知,C++對象中只保存非靜態(tài)數(shù)據(jù)成員,成員函數(shù)和靜態(tài)數(shù)據(jù)成員是存儲在靜態(tài)數(shù)據(jù)區(qū)的。

字節(jié)對齊(默認):

1、VC規(guī)定各成員變量存放的起始地址相對于結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù)。

2、VC為了確保結(jié)構(gòu)的大小為結(jié)構(gòu)的字節(jié)邊界數(shù)(即該結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù))的倍數(shù),所以在為最后一個成員變量申請空間后,還會根據(jù)需要自動填充空缺的字節(jié)。

3、如果對齊字節(jié)數(shù)(#pragma pack(n)),那么

(1)各成員變量存放的起始地址相對于結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)和n的較小值的倍數(shù)。

(2)結(jié)構(gòu)的大小為結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)和n的較小值的倍數(shù)。

class A { 
 double d;
 static int i;
 void f() { std::cout << "A::f" << std::endl; }
}; // 8 byte,只有double數(shù)據(jù)成員占8字節(jié),成員函數(shù)和靜態(tài)數(shù)據(jù)成員不在對象中,而是在靜態(tài)數(shù)據(jù)區(qū)


class B { 
 int i; //4
 double j;//8
 char k; //
}; // 24 byte,考慮字節(jié)對齊, 4 + 4 + 8 + 1 + 7, 藍色的4是為了滿足條件1,黑色的7是為了滿足條件2。如果指定4字節(jié)對齊,4 + 8 + 1 + 3


class C { 
 virtual void f() { std::cout << "C::f" << std::endl; }
}; // 4 byte,虛函數(shù)表指針占4個字節(jié)


class D { 
};// 1 byte,沒有成員變量的結(jié)構(gòu)或類的大小為1,因為必須保證結(jié)構(gòu)或類的每一 個實例在內(nèi)存中都有唯一的地址

注:

1、如果有成員對象,直接把成員對象展開到外部對象中,然后按照字節(jié)對齊的規(guī)律求大小。

2、虛繼承的內(nèi)存分布為:虛類指針-》派生類成員數(shù)據(jù)-》基類成員數(shù)據(jù)。其對齊方案是:首先把派生類所有成員當成一個嵌套結(jié)構(gòu)體形式,位于最下面的基類的數(shù)據(jù)成員要保證自己對齊(首地址整除自己的字節(jié)數(shù)),但是不用在最下面添加字節(jié)保證整體是邊界長度的整數(shù)倍(因為基類成員共享,不能把派生類當成一個整體)。

3、如果對象中有數(shù)組,可以把數(shù)組展開到對象中,然后按照字節(jié)對齊的規(guī)律求大小。

4、為什么要進行字節(jié)對齊

計算機組成原理教導(dǎo)我們這樣有助于加快計算機的取數(shù)速度,否則就得多花指令周期了。為此,編譯器默認會對結(jié)構(gòu)體進行處理(實際上其它地方的數(shù)據(jù)變量也是如此),讓寬度為2的基本數(shù)據(jù)類型(short等)都位于能被2整除的地址上,讓寬度為4的基本數(shù)據(jù)類型(int等)都位于能被4整除的地址上,以此類推。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設(shè)為32位系統(tǒng))如果存放在偶地址開始的地方,那么一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,并對兩次讀出的結(jié)果的高低字節(jié)進行拼湊才能得到該32bit數(shù)據(jù)。

備注:visual studio 2010是按照默認方式進行字節(jié)對齊的 32位gcc按照4字節(jié)最齊

以上就是小編為大家?guī)淼腃++對象內(nèi)存分布詳解(包括字節(jié)對齊和虛函數(shù)表)全部內(nèi)容了,希望大家多多支持腳本之家~

相關(guān)文章

  • 尾遞歸詳細總結(jié)分析

    尾遞歸詳細總結(jié)分析

    關(guān)于遞歸操作,相信大家都已經(jīng)不陌生。簡單地說,一個函數(shù)直接或間接地調(diào)用自身,是為直接或間接遞歸
    2013-09-09
  • 怎么通過C語言自動生成MAC地址

    怎么通過C語言自動生成MAC地址

    以下是對使用C語言自動生成MAC地址的實現(xiàn)代碼進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-09-09
  • 詳解C語言實現(xiàn)推箱子的基本功能

    詳解C語言實現(xiàn)推箱子的基本功能

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)推箱子的基本功能的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++中的移動構(gòu)造函數(shù)及move語句示例詳解

    C++中的移動構(gòu)造函數(shù)及move語句示例詳解

    這篇文章主要給大家介紹了關(guān)于C++中移動構(gòu)造函數(shù)及move語句的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • C++實現(xiàn)簡單的希爾排序Shell Sort實例

    C++實現(xiàn)簡單的希爾排序Shell Sort實例

    這篇文章主要介紹了C++實現(xiàn)簡單的希爾排序Shell Sort實例,對于正在學(xué)習(xí)算法的朋友很有借鑒價值,需要的朋友可以參考下
    2014-07-07
  • C語言數(shù)據(jù)結(jié)構(gòu)之復(fù)雜鏈表的拷貝

    C語言數(shù)據(jù)結(jié)構(gòu)之復(fù)雜鏈表的拷貝

    復(fù)雜鏈表指的是一個鏈表有若干個結(jié)點,每個結(jié)點有一個數(shù)據(jù)域用于存放數(shù)據(jù),還有兩個指針域,其中一個指向下一個節(jié)點,還有一個隨機指向當前復(fù)雜鏈表中的任意一個節(jié)點或者是一個空結(jié)點。今天我們要實現(xiàn)的就是對這樣一個復(fù)雜鏈表復(fù)制產(chǎn)生一個新的復(fù)雜鏈表
    2021-11-11
  • EasyC++單獨編譯

    EasyC++單獨編譯

    這篇文章主要介紹了EasyC++單獨編譯,在上一篇當中,我們編寫好了頭文件coordin.h,現(xiàn)在我們要完成它的實現(xiàn)。需要的小伙伴可以先學(xué)習(xí)上一篇內(nèi)容然后一起與小編一起進入本篇內(nèi)容一起學(xué)習(xí)吧
    2021-12-12
  • Qt事件過濾實現(xiàn)點擊圖片的放大和縮小

    Qt事件過濾實現(xiàn)點擊圖片的放大和縮小

    這篇文章主要為大家詳細介紹了Qt事件過濾實現(xiàn)點擊圖片的放大和縮小,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++設(shè)計模式之Static Factory模式詳解

    C++設(shè)計模式之Static Factory模式詳解

    這篇文章主要為大家詳細介紹了C++設(shè)計模式之Static Factory模式的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評論