C++類的大小介紹
1、C++結(jié)構(gòu)體和類的關(guān)系
為什么講C++類的大小要提到結(jié)構(gòu)體呢,因?yàn)榭赡芎芏嗪臀乙粯拥膶W(xué)子,接觸過(guò)C語(yǔ)言的結(jié)構(gòu)體對(duì)齊,但不明白類的大小怎么計(jì)算,這其中都要用到內(nèi)存對(duì)齊的概念,對(duì)于內(nèi)存對(duì)齊的概念之前已經(jīng)說(shuō)過(guò)了,可以參考這篇博客:C++結(jié)構(gòu)體字節(jié)對(duì)齊和共用體大小 明白結(jié)構(gòu)體的內(nèi)存大小計(jì)算后,就要明白類和結(jié)構(gòu)體的關(guān)系:
在C++中,結(jié)構(gòu)體和類的唯一區(qū)別就是: 結(jié)構(gòu)體和類具有不同的默認(rèn)訪問(wèn)控制屬性。
類中,對(duì)于未指定訪問(wèn)控制屬性的成員,其訪問(wèn)控制屬性為私有類型(private)。
結(jié)構(gòu)體中,對(duì)于未指定任何訪問(wèn)控制屬性的成員,其訪問(wèn)控制屬性為公有類型(public)。
所以結(jié)構(gòu)體的大小和類的大小是一樣的,在C++中,結(jié)構(gòu)體也可以實(shí)現(xiàn)實(shí)現(xiàn)繼承和多態(tài)(可能很驚訝,可以去看看這篇博文:C++結(jié)構(gòu)體與類的區(qū)別詳情,還要明確,靜態(tài)成員變量和成員函數(shù)所占用的空間肯定不是結(jié)構(gòu)體或類的空間。還有就是空的類的大小是1字節(jié),以方便類進(jìn)行實(shí)例化。
代碼進(jìn)行驗(yàn)證:
#include <iostream>
using namespace std;
struct Node {
};
class Test{
};
int main () {
cout << "sizeof(struct Node) = " << sizeof(Node) << endl;
cout << "sizeof(class Test) =" << sizeof(Test) << endl;
system("pause");
return 0;
}
代碼運(yùn)行結(jié)果為:

2、繼承類的大小
繼承允許我們依據(jù)另一個(gè)類來(lái)定義一個(gè)類,會(huì)把一個(gè)類的成員大小都繼承下來(lái),所以繼承了的派生類大小一定要考慮基類的大小,首先考慮的最大對(duì)齊數(shù),派生類的最大對(duì)齊數(shù)要考慮基類的最大對(duì)齊數(shù)。
下面以實(shí)際代碼進(jìn)行說(shuō)明:
#include <iostream>
using namespace std;
class Base{
public:
void func() { //成員函數(shù)不占用類的空間大小
}
private:
static int m_val1; // 靜態(tài)成員不占用類的空間
int m_valInt;
char m_valChar;
double m_valDouble;
};
class Son:public Base{
public:
static int func() { //靜態(tài)成員函數(shù)也不占用內(nèi)存空間
return 0;
}
private:
int m_sonValint;
};
int main () {
cout << "sizeof(Base) = " << sizeof(Base) << endl;
cout << "sizeof(Son) = " << sizeof(Son) << endl;
system("pause");
return 0;
}
代碼運(yùn)行結(jié)果為:

可以明確,靜態(tài)成員變量和成員函數(shù)所占用的空間類的空間,所以Base類的最大對(duì)齊數(shù)為double類型的大小(8字節(jié)),按照順序存儲(chǔ),
Base類的大小計(jì)算應(yīng)該為:
sizeof(Base)= 4 + 1 + 3(浪費(fèi)) + 8 = 16字節(jié)
Son類繼承了Base類,它的最大對(duì)齊數(shù)也就是8字節(jié),
所以Son類的大小計(jì)算應(yīng)該為:
sizeof(Son) = 4 + 1 + 3(浪費(fèi)) + 8 + 8 = 24字節(jié)
注意類的也要考慮存儲(chǔ)順序,如果把Base類中的m_valChar放到m_valDouble后面,
Base類的大小計(jì)算就變成了:
sizeof(Base)= 4 + 4(浪費(fèi))+ 8 + 1 + 7(浪費(fèi))= 24字節(jié)
Son類的大小就算就變成了:
sizeof(Son)= 4 + 4(浪費(fèi))+ 8 + 1 + 3(浪費(fèi)) + 4= 24字節(jié)
由此可以推算出多繼承類的大小計(jì)算,菱形繼承也是一樣,都會(huì)繼承基類的內(nèi)存,尤其注意虛繼承的情況,虛繼承只是避免了菱形繼承出現(xiàn)的二義性,但不是不繼承,
如以下代碼:
#include <iostream>
using namespace std;
class Base{
public:
void func() { //成員函數(shù)不占用類的空間大小
}
public:
double m_valDouble;
};
class Son1:virtual public Base{}; //虛繼承
class Son2:virtual public Base{}; //虛繼承
class GrandSon:public Son1,public Son2{};
int main () {
cout << "sizeof(GrandSon) = " << sizeof(GrandSon) << endl;
GrandSon gs;
// gs.m_valDouble = 10; //如果不是虛繼承就會(huì)出現(xiàn)二義性
system("pause");
return 0;
}
代碼運(yùn)行結(jié)果為:

上述GrandSon的依舊為16字節(jié),因?yàn)樗鼜腟on1繼承來(lái)了一份,又從Son2繼承來(lái)了一份,所以,虛繼承只是避免了訪問(wèn)的二義性,也可見(jiàn)菱形繼承會(huì)對(duì)內(nèi)存空間造成浪費(fèi) 。
3、多態(tài)類的大小
多態(tài)類唯一的區(qū)別就是計(jì)算類大小要考慮到虛寒表指針的大小,指針的大小和系統(tǒng)相關(guān),32位機(jī)器為4字節(jié),64位機(jī)器為8字節(jié),指針的大小也要作為最大對(duì)齊數(shù)的考慮范圍。
代碼說(shuō)明如下:
#include <iostream>
using namespace std;
class Base{
public:
virtual void func() = 0; //純虛函數(shù),會(huì)生成虛函數(shù)表指針
public:
char m_valChar;
};
class Son: public Base{
public:
void func() {};
public:
int m_SonvalInt;
};
int main () {
cout << "sizeof(Base) = " << sizeof(Base) << endl;
cout << "sizeof(Son) = " << sizeof(Son) << endl;
system("pause");
return 0;
}
代碼運(yùn)行結(jié)果為:

Base類的大小為8字節(jié),是因?yàn)樘摵瘮?shù)表指針占用了4字節(jié),所以Base類的最大對(duì)齊數(shù)為4字節(jié),虛函數(shù)表在構(gòu)造函數(shù)的時(shí)候就會(huì)生成,所以,虛函數(shù)表指針肯定優(yōu)先存儲(chǔ),
所以Base類大小的計(jì)算為:
sizeof(Base) = 4 + 1 + 3(浪費(fèi)) = 8字節(jié)
則Son類的大小計(jì)算為:
sizeof(Son)= 4 + 1 + 3(浪費(fèi)) + 4 = 12字節(jié)
到此這篇關(guān)于C++類的大小介紹的文章就介紹到這了,更多相關(guān)C++類的大小內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
LeetCode題解C++生成每種字符都是奇數(shù)個(gè)的字符串
這篇文章主要為大家介紹了LeetCode題解C++生成每種字符都是奇數(shù)個(gè)的字符串示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
C++缺省參數(shù)與重載函數(shù)(超詳細(xì)!)
無(wú)論使用什么語(yǔ)言函數(shù)都是代碼段中必不可少的部分,因此我們有必要深入認(rèn)識(shí)一下C++中函數(shù)的兩種特殊用法,缺省參數(shù),函數(shù)重載,這篇文章主要給大家介紹了關(guān)于C++缺省參數(shù)與重載函數(shù)的相關(guān)資料,需要的朋友可以參考下2024-06-06
C++ 使用VS Code運(yùn)行程序時(shí)終端輸出中文亂碼的解決辦法
這篇文章主要介紹了C++ 使用VS Code運(yùn)行程序時(shí)終端輸出中文亂碼的解決辦法 ,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07
15種?C++?常見(jiàn)報(bào)錯(cuò)原因分析
這篇文章主要介紹了15種?C++?常見(jiàn)報(bào)錯(cuò),本文通過(guò)實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01
用C語(yǔ)言實(shí)現(xiàn)圣誕樹(shù)(簡(jiǎn)易版+進(jìn)階版)
大家好,本篇文章主要講的是用C語(yǔ)言實(shí)現(xiàn)圣誕樹(shù)(簡(jiǎn)易版+進(jìn)階版),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
C++中將Char轉(zhuǎn)換成String的4種方法
本文主要介紹了C++中將Char轉(zhuǎn)換成String的4種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
淺析char 指針變量char *=p 這個(gè)語(yǔ)句的輸出問(wèn)題
下面小編就為大家?guī)?lái)一篇淺析char 指針變量char *=p 這個(gè)語(yǔ)句的輸出問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05

