C++——類例項化記憶體的分配和this指標的使用
一、類的例項化分配記憶體
類是結構體的演變,是一種資料型別,如int和char一樣是型別。那麼在類例項化時,記憶體是怎樣分配的呢?
步驟是:(可以通過程式碼考證)
1.屬性、方法不需要初始化,因為這些全部是指標。
2.初始化派生類的靜態欄位。
3.初始化派生類的非靜態欄位。
4.初始化基類的靜態欄位。
5.初始化基類的非靜態欄位。
6.呼叫基類的建構函式。
7.呼叫派生類的建構函式。
類分為成員變數和成員函式,我們先來討論成員變數。
一個類物件的地址就是類所包含的這一片記憶體空間的首地址,這個首地址也就對應具體某一個成員變數的地址。(在定義類物件的同時這些成員變數也就被定義了)我們來以一段程式碼說明問題:
//類的定義
class K{
public:
K(){k = 12;}
~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
當K kTemp 時,(new k()有待考證)就真正在Heap中例項化了一個物件,這個時候也將Heap上的地址寫入了K在Stack中的記憶體地址。K有了Reference,且指向了其在Heap中的物件。
例項化Heap中的物件時,簡單的成員變數(貌似還有屬性等)一樣是繼續在Stack上隨例項單獨分配記憶體地址。而類中的方法則是由物件們共享的。
二、this的使用
1.this在成員函式的開始前構造,在成員的結束後清除。這個生命週期同任何一個函式的引數是一樣的,沒有任何區別。
因為,成員函式預設第一個引數就是this。
舉例:
class A{
public:
int func(int p){}
};
func的原型在編譯器看來,應該是
int func(A* const this, int p);
即開始執行成員函式之前,構造。
成員函式執行結束,清除。
2.this指標的的存放位置
(1)this指標的存放位置和編譯器相關,可能是棧,暫存器,全域性變數區
3.this指標的是如何傳遞給類中函式的
(1)大多數編譯器通過eax暫存器傳遞this指標。在呼叫之前,編譯器會把對應的物件地址放在eax暫存器中
4.我們取得一個物件時,可以獲取其this指標。如果知道一個物件this指標的位置,能夠直接使用嗎?
(1)this指標只有在成員函式中才有定義。只有在成員函式中,是可以通過&this獲得地址的,也可以直接使用它。
(2)如果獲得一個物件,也不能通過物件使用this指標。
5.每個類編譯後,是否會產生一個類中函式表來儲存函式指標?
普通的函式(成員函式,靜態函式)都不會產生一個函式表,只有虛擬函式才會被放入函式表。
即使是虛擬函式,當編譯器明確呼叫哪個函式時,也會直接呼叫,不會通過函式表的指標呼叫。
6.this指標的作用域this指標只在非靜態函式中存在,所以靜態函式不能使用this指標為非靜態變數賦值。[待考證]
http://blog.sina.com.cn/s/blog_725dd1010100u12f.html這篇文章的最後有講解繼承的一些概念,以後學習。另外EAX的暫存器是什麼?