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

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

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

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

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

2、何時(shí)進(jìn)行動(dòng)態(tài)綁定:

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

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

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

3、C++中類的大?。?/strong>

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

字節(jié)對(duì)齊(默認(rèn)):

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

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

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

(1)各成員變量存放的起始地址相對(duì)于結(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ù)成員不在對(duì)象中,而是在靜態(tài)數(shù)據(jù)區(qū)


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


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


class D { 
};// 1 byte,沒(méi)有成員變量的結(jié)構(gòu)或類的大小為1,因?yàn)楸仨毐WC結(jié)構(gòu)或類的每一 個(gè)實(shí)例在內(nèi)存中都有唯一的地址

注:

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

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

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

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

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

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

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

相關(guān)文章

  • 詳解C++中的異常和錯(cuò)誤處理機(jī)制

    詳解C++中的異常和錯(cuò)誤處理機(jī)制

    在C++編程中,異常處理和錯(cuò)誤處理機(jī)制是非常重要的,它們可以幫助程序員有效地處理運(yùn)行時(shí)錯(cuò)誤和異常情況,本文就來(lái)介紹一下C++中的異常處理和錯(cuò)誤處理機(jī)制吧
    2023-05-05
  • iostream與iostream.h的區(qū)別詳細(xì)解析

    iostream與iostream.h的區(qū)別詳細(xì)解析

    以下是對(duì)C++中iostream與iostream.h的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09
  • c++中new的三種用法詳細(xì)解析

    c++中new的三種用法詳細(xì)解析

    以下的是對(duì)c++中new的三種使用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-09-09
  • 基于C語(yǔ)言實(shí)現(xiàn)UDP服務(wù)器

    基于C語(yǔ)言實(shí)現(xiàn)UDP服務(wù)器

    這篇文章主要為大家詳細(xì)介紹了如何使用C語(yǔ)言編寫一個(gè)簡(jiǎn)單的UDP服務(wù)器程序,以及如何接收和處理客戶端發(fā)送的數(shù)據(jù),有需要的小伙伴可以了解下
    2024-10-10
  • C++?pimpl機(jī)制詳細(xì)講解

    C++?pimpl機(jī)制詳細(xì)講解

    PIMPL?是?C++?中的一個(gè)編程技巧,意思為指向?qū)崿F(xiàn)的指針。具體操作是把類的實(shí)現(xiàn)細(xì)節(jié)放到一個(gè)單獨(dú)的類中,并用一個(gè)指針進(jìn)行訪問(wèn)
    2022-08-08
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++ 17標(biāo)準(zhǔn)正式發(fā)布! 更簡(jiǎn)單地編寫和維護(hù)代碼

    C++ 17標(biāo)準(zhǔn)正式發(fā)布! 更簡(jiǎn)單地編寫和維護(hù)代碼

    C++ 17 標(biāo)準(zhǔn)正式發(fā)布:終于能更簡(jiǎn)單地編寫和維護(hù)代碼了!本文為大家介紹了C ++ 17 主要特性,感興趣的小伙伴們可以參考一下
    2017-12-12
  • C++實(shí)現(xiàn)LeetCode(74.搜索一個(gè)二維矩陣)

    C++實(shí)現(xiàn)LeetCode(74.搜索一個(gè)二維矩陣)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(74.搜索一個(gè)二維矩陣),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 如何利用Matlab繪制出好看的火山圖

    如何利用Matlab繪制出好看的火山圖

    火山圖是散點(diǎn)圖的一種,它將統(tǒng)計(jì)測(cè)試中的統(tǒng)計(jì)顯著性量度和變化幅度相結(jié)合,從而能夠幫助快速直觀地識(shí)別那些變化幅度較大且具有統(tǒng)計(jì)學(xué)意義的數(shù)據(jù)點(diǎn)。本文將通過(guò)Matlab繪制好看的火山圖,需要的可以參考一下
    2022-03-03
  • C++ 打開(kāi)選擇文件夾對(duì)話框選擇目錄的操作

    C++ 打開(kāi)選擇文件夾對(duì)話框選擇目錄的操作

    這篇文章主要介紹了C++ 打開(kāi)選擇文件夾對(duì)話框選擇目錄的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01

最新評(píng)論