涉及到c++中求類大小時需要特別注意一下幾點
1.為類的非靜態成員資料的型別大小之和.
2.有編譯器額外加入的成員變數的大小,用來支援語言的某些特性(如:指向虛函式的指標、虛繼承、多重繼承).
3.為了優化訪問效率,進行的邊緣調整.
4. 與類中的建構函式,析構函式以及其他的成員函式無關.
5. 私有繼承,會去繼承之前的私有成員變數麼? 會...在記憶體中仍然分配相應的空間,只是在子類中是不可見的!
6. 在做多層次的繼承類大小時某個子類的類大小總是等於父類的大小加上子類中資料成員和是否有虛函式,是否是虛繼承等因素來決定。
首先:我們要知道什麼是類的例項化,所謂類的例項化就是在記憶體中分配一塊位址.
那我們先看看乙個例子:
#include
class a {};
class b{};
class c:public a;
class d:public b,public c{};
int main()
程式執行的輸出結果為:
sizeof(a) =1
sizeof(b)=1
sizeof(c)=4
sizeof(d)=8
上面是在vc++6.0編譯的結果,但是在dev-c++和code::blocks下得出的結果是 sizeof( d ) = 4
為什麼會出現這種結果呢?初學者肯定會很煩惱是嗎?類a,b明明是空類,它的大小應該為為0,為什麼 編譯器輸出的結果為1呢?這就是我們剛才所說的例項化的原因(空類同樣可以被例項化),每個例項在記憶體中都有乙個獨一無二的位址,為了達到這個目的,編譯器往往會給乙個空類隱含的加乙個位元組,這樣空類在例項化後在記憶體得到了獨一無二的位址.所以a,b的大小為1.
[cpp]
#include
using namespace std;
class a
private:
char k[3];
}; class b: public a
}; int main()
private:
char k[3];
}; class b: virtual public a
}; int main()
vs和gcc下
執行結果:
a's size is 8
b's size is 12
說明:類b裡包含,繼承的char k[3],繼承的虛函式,類b的虛函式表裡有a::aa(),
因為是虛繼承,還有乙個指向父類的指標
,該指標為指向虛基類的指標(pointer to virtual base class)。考慮記憶體對齊,總大小為12。
#include
using namespace std;
class a;};
class b
;class c: public a,public b;};
int main();};
class b : public virtual a;};
class c: public virtual a;
char j[3];
public:
virtual void t(){};
};class d: public b,public c
;int main()
{cout<
最後得到的結果是 8 16 16 28
最主要的是sizeof(d): 4個char陣列,對齊後是16,又是多重繼承,那麼有兩個虛函式表的指標,又需要維護一分a類的指標,那麼是16+4*2+4=28...採用虛繼承,目的就是為了解決二義性和減小記憶體開銷,所以在d中只維護乙份a的指標便可。
虛繼承與虛函式表
一 虛繼承 1 include iostream using namespace std class bvoid fb class d1 virtual public bvoid fd1 class d2 virtual public bvirtual void vd2 void fd2 class...
虛函式,虛繼承與虛函式表
c 實現多型機制 模板技術,rtti 技術,虛函式技術,要麼是試圖做到在編譯時決議,要麼試圖做到執行時決議 虛函式 帶有 關鍵字的函式,並且不帶有 標誌的 虛繼承帶有 關鍵字的繼承,基類被稱為虛基類,會在自己物件的例項中產生虛基類指標 虛函式與菱形繼承的問題 當發生繼承時,如果派生類重寫了基類的虛函...
單繼承類的虛函式表
列印虛函式表 include include using namespace std class classa int m data1 int m data2 void func1 void func2 virtual void vfunc1 virtual void vfunc2 class cl...