深入分析C++中類(lèi)的大小
首先看一個(gè)例子:
#include <iostream>
using namespace std;
class A{};
class B
{
int b;
char c;
};
class C
{
int c1;
static int c2;
};
int C::c2 = 1;
class D:public C,public B{
int d;
};
int main()
{
cout<<"sizeof(A)="<<sizeof(A)<<endl;
cout<<"sizeof(B)="<<sizeof(B)<<endl;
cout<<"sizeof(C)="<<sizeof(C)<<endl;
cout<<"sizeof(D)="<<sizeof(D)<<endl;
return 0;
}
運(yùn)行結(jié)果為:
sizeof(A)=1
sizeof(B)=8
sizeof(C)=4
sizeof(D)=16
對(duì)于類(lèi)A來(lái)說(shuō),雖然A是一個(gè)空類(lèi),但為了便于空類(lèi)進(jìn)行實(shí)例化,編譯器往往會(huì)給它分配一個(gè)字節(jié),這樣A實(shí)例化后便在內(nèi)存中有了一個(gè)獨(dú)一無(wú)二的地址.對(duì)于類(lèi)B,B的大小應(yīng)為sizeof(int)+sizeof(char)=5,但是考慮內(nèi)存對(duì)齊,B的大小應(yīng)為8.對(duì)于類(lèi)C,類(lèi)的靜態(tài)成員變量被放在全局區(qū),和類(lèi)的普通成員并沒(méi)有放在一塊。類(lèi)的靜態(tài)成員被聲明后就已存在,而非靜態(tài)成員只有類(lèi)被實(shí)例化后才存在。所以C的大小為sizeof(int)=4。D的大小為B+C的大小+自身數(shù)據(jù)成員的大小,一共為16.
==========================分割線在這里====================================
下面討論含有虛函數(shù)的類(lèi)的大小:
#include <iostream>
using namespace std;
class A
{
public:
void virtual aa(){};
};
class B:public A
{
void virtual bb(){};
};
class C:virtual A
{
public:
void virtual aa(){};
void cc(){};
};
class D:virtual A
{
public:
void virtual dd(){};
};
int main()
{
cout<<"sizeof(A)="<<sizeof(A)<<endl;
cout<<"sizeof(B)="<<sizeof(B)<<endl;
cout<<"sizeof(C)="<<sizeof(C)<<endl;
cout<<"sizeof(D)="<<sizeof(D)<<endl;
return 0;
}
運(yùn)行結(jié)果為:
sizeof(A)=4
sizeof(B)=4
sizeof(C)=8
sizeof(D)=12
對(duì)于class A,它含有一個(gè)虛函數(shù),編譯器會(huì)為虛函數(shù)生成一張?zhí)摵瘮?shù)表,來(lái)記錄對(duì)應(yīng)的函數(shù)地址,為此,在class A的內(nèi)存地址中要有一個(gè)vfptr_A指針指向這個(gè)虛表,所以class A的大小為指針大小,即4.(注意,無(wú)論類(lèi)中有多少個(gè)虛函數(shù),它們的大小都是4,因?yàn)閮?nèi)存中只需要保存這個(gè)指針即可)。
對(duì)于class B,它是public繼承A,雖然它也有一個(gè)虛函數(shù),但是從結(jié)果看,B應(yīng)該和A都在B的vtable(虛表中),所以class B的大小為4.
對(duì)于class C,它是vitual 繼承A,所以要有一個(gè)指向父類(lèi)A的指針,占有4字節(jié)大小aa()是繼承自class A的虛函數(shù),從結(jié)果來(lái)看,它沒(méi)有在內(nèi)存中占有空間,所以C的大小為sizeof(A)+4=8.
對(duì)于class D,它是虛繼承class A,同上,要有一個(gè)指向父類(lèi)A的指針,同時(shí),class D中有虛函數(shù),所以要有一個(gè)指向虛表的指針,所以sizeof(D)=sizeof(A)+4+4=12
相關(guān)文章
淺談Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用
這篇文章主要介紹了Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用,Glib庫(kù)在多線程編程中經(jīng)??梢杂玫?需要的朋友可以參考下2016-02-02
C++利用easyx圖形庫(kù)實(shí)現(xiàn)創(chuàng)意天天酷跑小游戲
這篇文章主要為大家詳細(xì)介紹了C++如何利用easyx圖形庫(kù)實(shí)現(xiàn)創(chuàng)意小游戲——天天酷跑,文中的示例代碼講解詳細(xì),快跟隨小編一起了解一下吧2023-03-03
C/C++ ip地址與int類(lèi)型的轉(zhuǎn)換實(shí)例詳解
這篇文章主要介紹了C/C++ ip地址與int類(lèi)型的轉(zhuǎn)換實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例代碼,實(shí)現(xiàn)思路及實(shí)現(xiàn)方法,需要的朋友可以參考下2016-12-12
C++動(dòng)態(tài)規(guī)劃之最長(zhǎng)公子序列實(shí)例
這篇文章主要介紹了C++動(dòng)態(tài)規(guī)劃之最長(zhǎng)公子序列,實(shí)例分析了C++求最長(zhǎng)公子序列的相關(guān)技巧,是C++字符串操作的一個(gè)典型應(yīng)用,需要的朋友可以參考下2015-04-04C語(yǔ)言中各種操作符的詳細(xì)介紹(純干貨?。?/a>
指令系統(tǒng)的每一條指令都有一個(gè)操作符,它表示該指令應(yīng)進(jìn)行什么樣性質(zhì)的操作,不同的指令用操作符這個(gè)字段的不同編碼來(lái)表示,每個(gè)編碼代表一種指令,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中操作符的相關(guān)資料,需要的朋友可以參考下2021-06-06
C語(yǔ)言實(shí)現(xiàn)電子郵件地址驗(yàn)證程序
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)電子郵件地址驗(yàn)證程序,利用的是POSIX正則表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-11-11
C++類(lèi)與對(duì)象之運(yùn)算符重載詳解
運(yùn)算符重載的方法是定義一個(gè)重載運(yùn)算符的函數(shù),在需要執(zhí)行被重載的運(yùn)算符時(shí),系統(tǒng)就自動(dòng)調(diào)用該函數(shù),以實(shí)現(xiàn)相應(yīng)的運(yùn)算。也就是說(shuō),運(yùn)算符重載是通過(guò)定義函數(shù)實(shí)現(xiàn)的2021-10-10

