結構體 類的成員變數 成員函式是如何分配記憶體的?

2021-06-20 02:49:29 字數 2929 閱讀 1450

類的成員函式是如何分配記憶體的?

類的成員函式的**定義在pe檔案的**區,所以從程式載入時,就已經分配好了記憶體用於存放這些**;**執行時所需要的記憶體,比如棧、堆等等,則是**執行時才分配的;對於某個類的所有物件來說,類成員函式只在記憶體中有乙份拷貝,所有的物件都共享同乙份成員函式的**。同乙個類的不同的物件之間的差異僅僅是通過成員變數來體現的。

關於結構體和c++類的記憶體位址問題

c++類是由結構體發展得來的,所以他們的成員變數(c語言的結構體只有成員變數)的記憶體分配機制是一樣的。下面我們以類來說明問題,如果類的問題通了,結構體也也就沒問題啦。 類分為成員變數和成員函式,我們先來討論成員變數。 乙個類物件的位址就是類所包含的這一片記憶體空間的首位址[cpp]

view plain

copy

print?

class

k    

~k(){}  

intk;  

};   

k ktemp;  

printf("%d--%d\n"

,&ktemp,&ktemp.k);  

printf("%d--%d\n"

,sizeof

(k),

sizeof

(ktemp.k));  

int*i = (

int*)(&ktemp);  

intw = *i;  

printf("%d\n"

,w);   

執行上面的**,結果如下:

1310588--1310588

4--4

12很明顯,類的記憶體大小和其唯一的成員變數的記憶體大小是一致的。記憶體位址也是一致的。他們甚至可以相互轉換。換成結構體結果也是一樣。。

那麼成員函式又如何?

上面得**就好像類沒有任何成員函式一樣,根本說明不了問題。 呵呵

所有的函式都是存放在**區的,不管是全域性函式,還是成員函式

。要是成員函式占用類的物件空間,那麼將是多麼可怕的事情:定義一次類物件就有成員函式占用一段空間。 我們再來補充一下靜態成員函式的存放問題吧:

靜態成員函式與一般成員函式的唯一區別就是沒有this指標

因此不能訪問非靜態資料成員,就像我前面提到的,所有函式都存放在**區,靜態函式也不例外。所有有人一看到 static 這個單詞就主觀的認為是存放在全域性資料區,那是不對的

c++是一種物件導向的程式語言,它向下保持了對c的相容,同時也允許程式設計師能夠自由的操控記憶體,雖然會帶來一些問題,但這不是我們要**的問題,略過不表。類是對某種物件的定義,包含變數和方法,也可以理解為現實生活中一類具有共同特徵的事務的抽象,他是物件導向語言的基礎。所以類是不占有記憶體的,可是如果類生成例項那麼將會在記憶體中分配一塊記憶體來儲存這個類。

類的例項在記憶體中是如何分配記憶體的,有什麼需要我們注意的,下面將慢慢到來。

比如下面乙個類:

class a

{};從形式上看,它似乎什麼有沒有,事實上它不止隱含了乙個建構函式和乙個析構函式,還有一些操作符過載函式,比如「=」。如果類a被例項話,如a a;在記憶體會佔據多大的空間呢?有人可能會說4,也有人會說0,還有人會說1,說1的就對了,為什麼會是1呢?原因有很多,如果我們定義乙個陣列a b[10];如果上面是0,這樣的局面將會很尷尬,所以a這樣乙個空類,編譯器會給它乙個位元組來填充。

增加乙個變數,(位元組對齊預設都是4)

[cpp]

view plain

copy

print?

class

a    

類a的例項將佔據4個位元組的記憶體,sizeof(a) = 4

變數i 的初值被編譯器指定位0xcdcdcdcd。

再增加乙個變數,

[cpp]

view plain

copy

print?

class

a    

此時按照變數生命的先後順序,i被放在低位址上,l緊隨其後。

例項占用8個位元組,sizeof(a) = 4*2 = 8

如果類裡面含有函式:

class a

};有些人可能會說類的大小是12,事實上sizeof(a) = 8;

為什麼會這樣,這是因為sizeof訪問的程式的資料段,而函式位址則被儲存在**段內,所以最後的結果是8.

再看下面這個情況

[cpp]

view plain

copy

print?

class

a  ;  

};  

此時sizeof(a)大小仍為8,這裡留給讀者去思考為什麼?(^-^)。

當類裡面含有虛函式時,情況會如何呢?

[cpp]

view plain

copy

print?

class

a  ;  

intadd(

intx,

inty);  

};  

因為含有虛函式,所以類裡面將含有乙個虛指標vptr,指向該類的虛表vtbl,乙個指標占用四位元組的位址,所以sizeof(a) = 12

虛指標放在類例項位址的最低位置,

比如 a *a = new a; 

我們可以這樣給變數i賦值

int *p = (int *)a;

p++;

*p = 1;//把i的值賦為1.

如果類作為派生類,記憶體將如何分配呢?

這種情況雖然有些複雜,但並不是說不好理解。

他有多少個父類每個父類的大小加起來在加上自身就是sizeof的大小。

靜態成員變數成員函式

靜態成員變數 1 定義靜態成員變數 關鍵字static可以用於說明乙個類的成員,靜態成員提供了乙個同類物件的共享機制 把乙個類的成員說明為static時,這個類無論有多少個物件被建立,這些物件共享這個static成員 靜態成員區域性於類,它不是物件成員 includeusing namespace ...

靜態成員變數成員函式

1.先來介紹它的第一條也是最重要的一條 隱藏。static函式,static變數均可 當同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。舉例來說明。同時編譯兩個原始檔,乙個是a.c,另乙個是main.c。char a a global variable void m...

結構體變數成員的位元組對齊

本文參考 在做一道題是發現結構體的長度並不簡單的等於各成員長度之和。受限於硬體平台,為了使不同平台下都能正確讀取記憶體單元的資料,變數需以特定的位址進行儲存。需滿足以下三條準則 1 結構體變數的首位址能被其最寬基本型別成員大小所整除 2 結構體成員相對於結構體首位址的偏移量都是成員大小的整數倍,如有...