從記憶體和物件的角度看C 類的靜態

2021-07-07 10:42:37 字數 1637 閱讀 8329

提綱:

1,c++的記憶體分割槽:stack heap和靜態儲存區;

2,靜態物件和例項物件;

3,使用規則;

4,應用場景;

一、c++的記憶體分割槽和物件模型

參考《c++primer plus》第9章「記憶體模型和命名空間」,c++中用「持續性、作用域和鏈結性」三個屬性來表徵其儲存特性,包括變數和函式。c++的記憶體模型大致可以分為三塊:堆(heap)、棧(stack)和靜態儲存區(可能有第四塊儲存區,用於儲存函式,也有可能函式同全域性變數一樣,也是放在靜態儲存區)。其中,「堆」是乙個動態儲存區,存放執行時「new」出來的物件;「棧」存放區域性變數、函式引數(實參)、函式呼叫時的函式位址等;「靜態儲存區」存放(靜態)全域性變數、靜態區域性變數,可能還有函式。

程式載入的時候,是先載入(靜態)全域性變數,在進入「main()函式」按程式執行載入或生成其他物件,故靜態變數和普通變數不但儲存區域不同,載入的時間也不同。(靜態區域性變數也是在

「main()函式」之前載入的

)參考《c++primer plus》p309,「由於靜態變數的數目在程式執行期間是不變的,因此程式不需要使用特殊的裝置(如棧)來管理它們。編譯器將分配固定的記憶體塊來儲存所有的靜態變數,這些變數在整個程式執行期間一直存在。另外,如果沒有顯式地初始化靜態變數,編譯器將把它設定為0」。

c++中無靜態類,類必須在執行時進行例項化,即產生類的例項物件,該物件要麼儲存在棧,要麼儲存在堆中,雖然從語法上允許全域性的類物件,但實際使用在很少見到(待分析其原因)。類的普通成員變數和成員函式都需要通過類的例項物件來呼叫,其中,在類的內通過隱含的「this指標」進行呼叫。而類的靜態成員函式不能通過例項物件來呼叫,必須通過類名來呼叫,它的特性與全域性函式相似,僅僅是被類限定了作用域而已。

二、使用規則

1,靜態成員變數(以下簡稱靜態成員)

1)2)靜態成員不能在類定義裡邊初始化,只能在class body外初始化。

3)靜態成員仍然遵循public,private,protected訪問準則。

4)靜態成員不可在類體內賦值,因為它是被所有類物件共享的,在乙個物件內改變了,也會在其他物件中改變,造成混亂。為避免這種混亂,故限制它不可在類體內賦值。如果要改變靜態成員,可以通過靜態成員函式。

2,靜態成員函式

1)靜態成員函式沒有this指標,它不能返回非靜態成員,因為除了物件會呼叫它外,類本身也可以呼叫。

2)出現在類體外的函式定義不能指定關鍵字static;

3)靜態成員之間可以相互訪問,包括靜態成員函式訪問靜態資料成員和訪問靜態成員函式

4)非靜態成員函式可以任意地訪問靜態成員函式和靜態資料成員;

5)靜態成員函式不能直接訪問非靜態成員函式和非靜態資料成員;可以通過物件名呼叫非靜態成員函式,前提是要傳入物件到該靜態成員函式中。

6)由於沒有this指標的額外開銷,因此靜態成員函式與類的全域性函式相比速度上會有少許的增長;

7)呼叫靜態成員函式,可以用成員訪問操作符(.)和(->)為乙個類的物件或指向類物件的指標呼叫靜態成員函式,

當同一類的所有物件使用乙個量時,對於這個共用的量,可以用靜態資料成員變數,這個變數對於同一類的所有的物件都取相同的值。靜態成員變數只能被靜態成員函式呼叫。靜態成員函式也是由同一類中的所有物件共用。只能呼叫靜態成員變數和靜態成員函式。

參考csdn的部落格:

靜態成員變數和靜態成員函式

從靜態鏈結的角度看global static與宣告

就像搭積木,鏈結將不同的軟體模組組裝成乙個完整的可執行的程式。對於聯結器來說,軟體模組的基本單位是目標檔案,來自於某個原始檔。a.c要想引用乙個外部的函式或者變數,只需進行相應的宣告就可以。目標檔案以段 section 為單位將程式組織起來。鏈結大體上可以分為兩步 1.同名段合併。典型的合併就是兩個...

從類的記憶體結構看C 繼承

先看下面這個簡單的例子,我們建立乙個基類 base class 通過簡單的繼承 inherit 產生兩個派生類 derived class 然後通過乙個基類的指標去呼叫這兩個派生類,並且呼叫類中的函式。class base void show2 class derived1 public base ...

從彙編的角度看C 裡的引用和指標

c 裡有引用和指標,使用過c 的應該都知道它們的異同點。本文將從彙編的角度去觀察這2者的本質。使用也非常簡單,在左側編寫c 在右側就會直接顯示對應的組合語言,也可以根據需要的平台來選擇對應的編譯器 我們使用的c 如下,比較簡單 int main void 選擇的編譯器是x86 64 gcc 9.2,...