1.成員的分開存儲
C++通過將類的成員分開存儲的方式來實現面向對象
成員 | 存儲位置 |
---|---|
普通成員變量 | 棧區,與struct變量有相同的內存佈局和字節對齊方式 |
靜態成員變量 | 全局數據區,如此便可以使用類名和類所有的對象都可以訪問 |
成員函數 | 代碼段,包括靜態成員函數和非靜態成員函數 |
虛函數 | 虛函數表指針(vfptr)存放在棧區,其指向的虛函數表有自身的內存存儲空間 |
2.C++類的內存分佈
要想更好的瞭解這些,我們還需瞭解C++類的內存分佈
Stack:
棧,存放Automatic Variables,按內存地址由高到低方向生長,其最大大小由編譯時確定,速度快,但自由性差,最大空間不大。保存程序中的局部變量。
Heap:
堆,自由申請的空間,按內存地址由低到高方向生長,其大小由系統內存/虛擬內存上限決定,速度較慢,但自由性大,可用空間大。 動態分配的內存在調用malloc()或者相關函數產生,在調用free()時釋放,由程序員決定而不是一系列規則規定內存持續時間,因此內存塊可在一個函數中創建,在另一個函數中釋放。由於這點,動態內存分配容易導致堆區內存碎片化。
.Data:
存放程序中 已經初始化的非零全局變量。靜態分配。
data又可分爲讀寫(RW)區域和只讀(RO)區域。
- RO段保存常量所以也被稱爲
.constdata
eg const數據 - RW段則是普通非常全局變量,靜態變量就在其中
.Bss:
存放程序中未初始化的和零值全局變量。靜態分配,在程序開始時通常會被清零。
.Text:
也稱爲代碼段(Code),用來存放程序執行代碼,同時也可能會包含一些常量(如一些字符串常量等)。該段內存爲靜態分配,只讀(某些架構可能允許修改)。
這塊內存是共享的,當有多個相同進程(Process)存在時,共用同一個text段。
普通成員變量存儲在棧區,使得每一個類的對象都擁有各自獨立的普通成員變量。
靜態成員變量存儲在全局數據區,是的每一個類的對象都共享一份靜態
成員變量。
3.this指針
那麼,存放在代碼段的成員函數是怎麼區分調用對象的呢?
事實上, C++爲每一個函數都隱式定義了一個函數所屬類類型的指針形參–this,而this指針永遠指向調用函數的對象,如此函數便可以識別調用自身的是類的哪個對象了。
這裏有一點要注意, C++並沒有爲靜態成員函數定義this指針,如此,靜態成員函數被所有的對象共享。
4.總結
通過成員的分開存儲和普通成員函數的this指針
C++便可以識別各個不同的對象,如此便實現了面向對象。