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

詳解C++中類的大小決定因數(shù)

 更新時(shí)間:2025年04月07日 10:34:28   作者:點(diǎn)云SLAM  
類的大小受多個(gè)因素影響,主要包括成員變量、對齊方式、繼承關(guān)系、虛函數(shù)表等,下面就來介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下

在 C++ 中,類的大小(sizeof(ClassName))受多個(gè)因素影響,主要包括成員變量、對齊方式、繼承關(guān)系、虛函數(shù)表等。以下是影響類大小的關(guān)鍵因素:

1. 非靜態(tài)數(shù)據(jù)成員

類的大小主要取決于其非靜態(tài)成員變量的大小。

  • 靜態(tài)成員變量 不影響 類的大?。ù鎯υ谌?jǐn)?shù)據(jù)區(qū))。
  • 非靜態(tài)成員變量 占用對象的存儲空間。

示例:

class A {
    int x;   // 4 bytes
    char y;  // 1 byte (可能有填充)
};
std::cout << sizeof(A) << std::endl; // 可能是 8,而不是 5

由于結(jié)構(gòu)體對齊(Padding),sizeof(A) 可能是 8,而不是 5(見對齊規(guī)則)。

2. 數(shù)據(jù)對齊(Padding)

編譯器會對數(shù)據(jù)進(jìn)行內(nèi)存對齊,以提高 CPU 訪問效率。

  • 變量的地址需要符合其對齊要求(如 int 需要 4 字節(jié)對齊)。
  • 可能會在成員之間填充字節(jié)(padding)。

示例:

class B {
    char a;   // 1 byte
    int b;    // 4 bytes, 但需要 4 字節(jié)對齊
    char c;   // 1 byte
};
  • char a 占 1 字節(jié),但后面填充 3 字節(jié)(以滿足 int b 的對齊)。
  • int b 占 4 字節(jié)。
  • char c 占 1 字節(jié),但后面填充 3 字節(jié)(類的大小需要是 int 的倍數(shù))。
  • 總大小 = 1 + 3 (填充) + 4 + 1 + 3 (填充) = 12 字節(jié)。

可以使用 #pragma pack(1) 強(qiáng)制取消對齊,但可能會影響性能:

#pragma pack(1) 
class C {
    char a;
    int b;
    char c;
};
#pragma pack()
std::cout << sizeof(C) << std::endl; // 可能是 6 而不是 12

3. 虛函數(shù)(vtable 指針)

如果類包含虛函數(shù),則對象會存儲一個(gè)指向虛函數(shù)表(vtable)的指針。

  • 該指針通常占 8 字節(jié)(64 位系統(tǒng))或 4 字節(jié)(32 位系統(tǒng))。
  • 即使沒有成員變量,類也會占用指針大小的空間。

示例:

class D {
    virtual void func() {}
};
std::cout << sizeof(D) << std::endl; // 8(64 位系統(tǒng)),4(32 位系統(tǒng))

僅包含虛函數(shù)的類,仍然占用 vtable 指針的大小。

如果是多重繼承且基類有虛函數(shù),每個(gè)基類都有自己的 vtable 指針:

class Base1 {
    virtual void foo() {}
};

class Base2 {
    virtual void bar() {}
};

class Derived : public Base1, public Base2 {
};
std::cout << sizeof(Derived) << std::endl; // 16(64 位系統(tǒng)),8(32 位系統(tǒng))

Derived 類有兩個(gè) vtable 指針,每個(gè)占 8 字節(jié)(64 位系統(tǒng))。

4. 繼承

  • 單繼承:子類包含父類的成員,并可能繼承 vtable 指針。
  • 多繼承:可能會導(dǎo)致多個(gè) vtable 指針,增加對象大小。
  • 虛繼承:由于需要額外存儲 虛基類指針(vbptr),可能增大對象大小。

普通繼承

class Base {
    int a;
};

class Derived : public Base {
    char b;
};
std::cout << sizeof(Derived) << std::endl; // 8(對齊后)

虛繼承

虛繼承需要維護(hù) 虛基類表指針(vbptr),導(dǎo)致額外的存儲開銷:

class Base {
    int a;
};

class Derived1 : virtual public Base {};
class Derived2 : virtual public Base {};

class Final : public Derived1, public Derived2 {};
std::cout << sizeof(Final) << std::endl; // 額外增加 vbptr

Final 可能比普通繼承的大小更大,因?yàn)?nbsp;vbptr 需要額外存儲虛基類地址。

5. 空類

空類在 C++ 里不是零大小,通常是 1 字節(jié),以保證兩個(gè)對象的地址不同:

class Empty {};
std::cout << sizeof(Empty) << std::endl; // 1

即使類為空,C++ 也會給它分配 1 字節(jié),以確保不同對象有唯一地址。

如果空類有虛函數(shù),它仍然包含 vtable 指針:

class EmptyVirtual {
    virtual void func() {}
};
std::cout << sizeof(EmptyVirtual) << std::endl; // 8(64 位系統(tǒng))

6. 位域(Bit Fields)

位域允許多個(gè)變量共享同一個(gè)字節(jié),減少存儲空間:

class BitField {
    unsigned int a : 1;  // 1 bit
    unsigned int b : 2;  // 2 bits
    unsigned int c : 3;  // 3 bits
};
std::cout << sizeof(BitField) << std::endl; // 4(存儲在一個(gè) int 中)

位域大小取決于其基礎(chǔ)類型(如 int),如果跨越邊界,可能導(dǎo)致額外填充。

7. 編譯器優(yōu)化

不同編譯器可能優(yōu)化類的布局,如:

  • 調(diào)整成員變量順序,減少填充字節(jié)。
  • 自動合并位域,提高空間利用率。

可以用 -Wpadded(GCC/Clang)檢查填充:

g++ -Wpadded myfile.cpp

總結(jié)

影響因素影響
非靜態(tài)成員直接影響類大小
數(shù)據(jù)對齊可能增加填充字節(jié)
虛函數(shù)增加 vtable 指針(通常 8 字節(jié))
繼承繼承成員、vtable,可能增加 vbptr
空類不是 0,而是 1 字節(jié)
位域可能優(yōu)化存儲,但依賴對齊
編譯器優(yōu)化可能調(diào)整成員順序

如果你需要最小化類的大小,可以:

  • 調(diào)整成員變量順序 以減少填充字節(jié)。
  • 避免不必要的虛函數(shù)(若無多態(tài)需求)。
  • 使用位域 以節(jié)省空間(但可能影響性能)。
  • 使用 #pragma pack 取消對齊(但可能降低訪問速度)。

到此這篇關(guān)于詳解C++中類的大小決定因數(shù)的文章就介紹到這了,更多相關(guān)C++類的大小決定因數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • WPF微信聊天和通訊錄按鈕樣式代碼分享

    WPF微信聊天和通訊錄按鈕樣式代碼分享

    這篇文章主要為大家分享了WPF微信聊天和通訊錄按鈕樣式代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • C#8.0 中開啟默認(rèn)接口實(shí)現(xiàn)方法

    C#8.0 中開啟默認(rèn)接口實(shí)現(xiàn)方法

    這篇文章主要介紹了C#8.0 中開啟默認(rèn)接口實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧的相關(guān)資料
    2019-05-05
  • Unity實(shí)現(xiàn)老虎機(jī)滾動抽獎效果的示例代碼

    Unity實(shí)現(xiàn)老虎機(jī)滾動抽獎效果的示例代碼

    這篇文章主要介紹了Unity實(shí)現(xiàn)老虎機(jī)滾動抽獎效果的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C#匿名委托和Java匿名局部內(nèi)部類使用方法示例

    C#匿名委托和Java匿名局部內(nèi)部類使用方法示例

    Java在嵌套類型這里提供的特性比較多,假設(shè):Java的字節(jié)碼只支持靜態(tài)嵌套類,內(nèi)部類、局部內(nèi)部類和匿名局部內(nèi)部類都是編譯器提供的語法糖,這個(gè)假設(shè)目前沒法驗(yàn)證(看不懂字節(jié)碼),本文先來看一下C#是如何為我們提供的這種語法糖
    2013-11-11
  • C#中abstract的用法詳解

    C#中abstract的用法詳解

    abstract可以用來修飾類,方法,屬性,索引器和時(shí)間,這里不包括字段. 使用abstrac修飾的類,該類只能作為其他類的基類,不能實(shí)例化,而且abstract修飾的成員在派生類中必須全部實(shí)現(xiàn),不允許部分實(shí)現(xiàn),否則編譯異常
    2016-12-12
  • C# Lambda 知識回顧

    C# Lambda 知識回顧

    本文主要介紹了C#中Lambda的相關(guān)知識。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • C# params可變參數(shù)的使用注意詳析

    C# params可變參數(shù)的使用注意詳析

    這篇文章主要給大家介紹了關(guān)于C# params可變參數(shù)的使用注意的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • C# FileStream讀寫的文本操作代碼分析

    C# FileStream讀寫的文本操作代碼分析

    這篇文章主要分享了個(gè)人使用C# FileStream實(shí)現(xiàn)的讀寫的文本操作的小程序,主要是復(fù)習(xí)下對filestream的理解,希望對大家學(xué)習(xí)C#能夠有所幫助
    2016-07-07
  • C#使用Datatable導(dǎo)入sqlserver數(shù)據(jù)庫的三種方法

    C#使用Datatable導(dǎo)入sqlserver數(shù)據(jù)庫的三種方法

    本文主要介紹了C#使用Datatable導(dǎo)入sqlserver數(shù)據(jù)庫的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • C# 中依賴注入(DI)的實(shí)現(xiàn)方式

    C# 中依賴注入(DI)的實(shí)現(xiàn)方式

    在C#中依賴注入(DI)的實(shí)現(xiàn)方式主要分為手動注入和通過IoC容器注入,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11

最新評論

津南区| 广东省| 潼关县| 泌阳县| 昌江| 邹平县| 普格县| 民勤县| 新昌县| 衡南县| 高陵县| 延边| 繁昌县| 玉林市| 雷山县| 桃园市| 永宁县| 兴城市| 河西区| 津南区| 洛南县| 石景山区| 洪洞县| 新平| 华阴市| 津市市| 吉林省| 龙江县| 碌曲县| 江达县| 儋州市| 榆树市| 资中县| 黄浦区| 靖远县| 新泰市| 台南县| 涪陵区| 左云县| 丹江口市| 繁峙县|