C++中的類所占內存空間總結


類所占內存的大小是由成員變量(靜態變量除外)決定的,成員函數(這是籠統的說,后面會細說)是不計算在內的。


示例如下:

(一)

class CBase 
{ 
}; 

sizeof(CBase)=1;

為什么空的類什么都沒有是 1 呢?

c++要求每個實例在內存中都有獨一無二的地址。空類也會被實例化,所以編譯器會給空類隱含的添加一個字節,這樣空類實例化之后就有了獨一無二的地址了。所以空類的 sizeof 為 1。


(二)

class CBase 
{ 
	int a; 
	char p; 
}; 

sizeof(CBase)=8;

記得對齊的問題,這點和 struct 的對齊原則很像!int 占 4 字節,char 占一字節,補齊 3 字節。


(三)

class CBase 
{ 
public: 
	CBase(void); 
	virtual ~CBase(void); 
    
private: 
	int  a; 
	char *p; 
}; 

sizeof(CBase)=12

C++ 類中有虛函數的時候有一個指向虛函數的指針,在 32 位系統分配指針大小為 4 字節。無論多少個虛函數,只有這一個指針,4 字節。注意一般的函數是沒有這個指針的,而且也不占類的內存。


(四)

class CChild : public CBase 
{ 
public: 
	CChild(void); 
	~CChild(void); 

virtual void test();
	private: 
	int b; 
}; 

sizeof(CChild)=16;

可見子類的大小是本身成員變量的大小加上父類的大小。其中有一部分是虛擬函數表的原因,父類子類共享一個虛函數指針。


(五)

#include<iostream.h>

class a {};

class b{};

class c:public a
{
	virtual void fun()=0;
};

class d:public b,public c
{
};

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;
}

sizeof(a)=1
sizeof(b)=1
sizeof(c)=4
sizeof(d)=8

注意第三種情況和第四種情況。


(六)

#include<iostream>
using namespace std;

class A
{
	char a[3];
public:
	virtual void fun1(){};
};

class B : public virtual A
{
	char b[3];
public:
	virtual void fun2(){};
};

class C : public virtual B
{
	char c[3];
public:
	virtual void fun3(){};
};

int main()
{
	cout << sizeof(A) << endl; // 8
	cout << sizeof(B) << endl; // 8(A) + 12(B)
	cout << sizeof(C) << endl; // 8(A) + 12(B) + 12(C)
	return 0;
}

sizeof(A)=8
sizeof(B)=20
sizeof(c)=32

注意,虛繼承的時候A B C三個類不僅不會共享虛基類指針,也不會共享虛表指針,要和普通繼承區分開來。


具體分析如下:

 class A size(8):
      +---
 0    | {vfptr}
 4    | a
      | <alignment member> (size=1)
      +---
 
 class B size(20):
      +---
 0    | {vfptr}
 4    | {vbptr}
 8    | b
      | <alignment member> (size=1)
      +---
      +--- (virtual base A)
12    | {vfptr}
16    | a
      | <alignment member> (size=1)
      +---
 
 class C size(32):
      +---
 0    | {vfptr}
 4    | {vbptr}
 8    | c
      | <alignment member> (size=1)
      +---
      +--- (virtual base A)
12    | {vfptr}
16    | a
      | <alignment member> (size=1)
      +---
      +--- (virtual base B)
20    | {vfptr}
24    | {vbptr}
28    | b
      | <alignment member> (size=1)
      +---

總結

空的類是會占用內存空間的,而且大小是 1,原因是 C++ 要求每個實例在內存中都有獨一無二的地址。

(一)類內部的成員變量:

  • 普通的變量:是要占用內存的,但是要注意對齊原則(這點和 struct 類型很相似)。
  • static 修飾的靜態變量:不占用內容,原因是編譯器將其放在全局變量區。

(二)類內部的成員函數:

  • 普通函數:不占用內存。
  • 虛函數:有一個指向虛函數的指針,要占用 4 個字節,用來指定虛函數的虛擬函數表的入口地址。所以一個類的虛函數所占用的地址是不變的,和虛函數的個數是沒有關系的。

說明:此博文轉載之http://blog.sina.com.cn/s/blog_69c189bf0100mkeu.html



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM