C 靜態變數記憶體分配,編譯階段,解密

2021-08-07 13:47:06 字數 1730 閱讀 9402

注意:

c++靜態成員變數是用static修飾的成員變數,不屬於物件的一部分,而是類一部分,因此可以在沒有例項化任何物件的時候使用靜態成員變數。但是必須初始化它。

之所以必須初始化它是因為:全域性靜態變數自動初始化,但是區域性變數

由於靜態變數只能被初始化一次,所以初始化成員變數不要放在如下地方:1.類的建構函式(建構函式可能多次被呼叫);2.標頭檔案中(標頭檔案可能被包含入多個地方,也可能被執行多次)。應該放在應用程式中,類以外的任何地方初始化,例如:在main中,或全域性函式中,或任何函式之外:

所有的物件(不僅僅是靜態物件)初始化都只有一次

因為a初始化為1之後,一直都沒有銷毀(因為是static),所以不會再次初始化

記憶體分配方式有三種:  

(1)從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static變數。  

(2)在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。  

(3)從堆上分配,亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意多少的記憶體,程式設計師自己負責在何時用free或delete釋放記憶體。動態記憶體的生存期由我們決定,使用非常靈活,但問題也最多。

類的靜態成員變數和函式中的靜態變數一樣,在編譯的時候就分配記憶體了,直到程式退出才釋放,並不是隨著物件的刪除而釋放的:

類的靜態成員變數為什麼必須得在類外初始化?

我 的理解: 由於靜態變數在編譯期間必須初始化,全域性變數的靜態或者非靜態的變數都可以賦初值0。而類中的變數要用建構函式來初始化,但是在編譯期間沒有創造物件,所 以就沒有執行構造方法。故在編譯期間沒有給類的靜態變數初始化。所以要在類外 main之前要給該靜態變數初始化,不管該靜態變數的作用域為private還是public,因為編譯期間private沒有影響。但是一旦進入執行 時,就不可以呼叫類中的private變數。

呼叫的時候可以通過物件呼叫,也可以通過類直接呼叫

class a

;class b

;int b::n = 1;    //靜態成員變數的初始化

a b::aobj;       //靜態成員變數的初始化(例項化)

void main()

私有的靜態成員變數也是放在類外初始化的.這看起來跟它的私有屬性不相符.

再做下面的測試,發現了乙個有趣的現象.

class b

;    //把這行注釋掉,輸出變成2

int p();

};int b::i = 2;      //把這行注釋掉,編譯報錯

void main()

1、「這樣看來.類外的初始化那一行根本沒有起到初始化的作用.它賦的值根本沒用.(對私有靜態成員變數是這樣.公有的還是有作用的)「  這句話是不對的!!!

因為 對於static成員變數是否是private資料並沒有影響,因為設定static成員變數初值時,不受任何訪問許可權的束縛,

而靜態變數賦值是在編譯階段,所以早於建構函式,當類宣告物件時 i=3覆蓋了前面的值。所以才是 3

2、當把b();注掉時,沒有了建構函式裡的賦值覆蓋,所以結果是2 ,親測

3、因為由於靜態變數只能被初始化一次,所以放在函式體外或全域性函式中

不過要注意的是,static成員變數的型別要出現在初始化語句中,因為這是初始化操作,不是賦值操作。static成員變數是在初始化(而不是在類宣告時候)才定義出來的。如果沒有初始化操作,會產生鏈結錯誤

記憶體分配(全域性,區域性,靜態變數,

記憶體分配 知識,全域性,區域性,靜態變數 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋...

記憶體分配, 全域性,區域性,靜態變數

預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由 os 注意它與資料結構...

記憶體分配 知識,全域性,區域性,靜態變數

預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中...