C 類物件成員變數與成員函式記憶體分配問題

2021-06-16 11:59:05 字數 2803 閱讀 5296

了解c++類位址的存放和分配等問題,能幫助我們更深入、更清晰了解類的組成及其使用。

自己目前不是很清楚,先收集一些網上資料,而後再慢慢補充增加的了解...

//-------------------------------------------網路收集之-------------------------------------

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

今天終於有時間寫點東西了~ 太爽了  *_*  很多人都知道c++類是由結構體發展得來的,所以他們的成員變數(c語言的結構體只有成員變數)的記憶體分配機制是一樣的。下面我們以類來說明問題,如果類的問題通了,結構體也也就沒問題啦。 類分為成員變數和成員函式,我們先來討論成員變數。 乙個類物件的位址就是類所包含的這一片記憶體空間的首位址,這個首位址也就對應具體某乙個成員變數的位址。(在定義類物件的同時這些成員變數也就被定義了)我們來以一段**說明問題: //類的定義

class k

~k(){}

int k;

}; //類的使用//... k ktemp;

printf("%d--%d\n",&ktemp,&ktemp.k);

printf("%d--%d\n",sizeof(k),sizeof(ktemp.k));

int *i = (int*)(&ktemp);

int w = *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)

class  a

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

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

再增加乙個變數,

class a

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

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

如果類裡面含有函式:

class a

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

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

再看下面這個情況

class a;};

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

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

class a

;int add(int x,int y);

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

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

比如 a *a = new a;

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

int *p = (int *)a;

p++;

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

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

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

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

總結:

1,  cout輸出十六進製制的妙法:cout<<(int*)18;

2,  在空類的物件中,其物件大小為1bit;

3,  static 的變數不會增加物件的大小;

4,  存在virtual函式時,物件大小增加4bit。

5,  當乙個類繼承了多個介面時,其記憶體排列順序為:

a) 第乙個繼承類的虛函式表的位址值。

b) 第乙個繼承類的非靜態成員變數

c) 第二個繼承類的虛函式表的位址值。

d) 第二個繼承類的非靜態成員變數

e) 如此一直交叉儲存下去。

6,  子類也具有虛函式時,其虛函式位址放在第乙個繼承類的虛函式表中。

7,  虛函式表的結構就是乙個個函式的位址的排列,最後以null結束。

C 類物件成員變數與成員函式記憶體分配問題

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

C 類物件成員變數與成員函式記憶體分配問題

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

C 成員變數與函式記憶體分配

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