關於全域性 static物件 變數的初始化問題

2021-04-12 23:29:34 字數 1842 閱讀 5034

關於全域性、static物件/變數的初始化問題

1. 全域性變數、static變數的初始化時機:main()函式執行之前(或者說main中第乙個使用者語句執行之前)。

2.初始化順序

1)全域性物件、外部static物件

a)同一編譯單元(同一原始檔)中,按照物件/變數的定義順序初始化。

b)不同編譯單元,c++標準未保證初始化先後順序,只保證都在main()之前初始化完成。

2)函式內部local static變數,在該函式呼叫過程中第一次遇到該static變數時初始化。

基於以上觀點,大師們建議少用全域性變數,全域性變數之間要消除依賴關係——特別是初始化依賴關係!

全域性變數的使用可以參考

scott meyers

在《more effective c++》中m34所說的,模擬singleton模式,通過函式內部的local static變數來代替全域性變數。

寫個示例程式驗證下這些變數的初始化,中間的注釋部分就作為上面結論的一些補充吧。

class ca

};public:

ca()

static void func1()

static void func2()

static cinner myinner2;

}public:

static int m_i1;

static int m_i2;

staticconstint m_i3;

static int m_i4;};

/* 不同模組的全域性、static變數/物件初始化順序不確定;

* 同乙個編譯模組按定義順序初始化。

* 但有一點相同,就是它們均在編譯期已分配好記憶體。

* 對於諸如基本資料型別,編譯期能確定其值的,編譯器就直接將值寫入分配的空間,如「ca::m_i1=3"。

* 對於編譯期不能確定值的,要等到執行時main函式之前初始化,如theca、ca::m_i2。

* 但若static的初始化表示式均為const或字面常量等確定的值,則亦能在編譯期確定值,如m_i4。

*/int ca::m_i1 = 1;

ca theca;

constint  ca::m_i3 = 3;

int ca::m_i2 = ca::m_i1 + 1;

int ca::m_i4 = ca::m_i3 + 1;

int main(int argc, _tchar* argv)

以上程式執行結果為:

constructor of ca.

m_i1 = 1, m_i2 = 0, m_i3 = 3, m_i4 = 4

in function func1().

constructor of inner class cinner

in function func2(), m_i1 = 1

m_i1 < 10 and constructor of cinner won't be called!

after ca::m_i1 increased by 11 :

in function func2(), m_i1 = 12

constructor of inner class cinner.

static全域性變數 全域性變數

1 全域性變數 外部變數 的說明之前再冠以static 就構成了靜態的全域性變數。全域性變數本身就是靜態儲存方式,靜態全域性變數當然也是靜態儲存方式。這兩者在儲存方式上並無不同。這兩者的區別在於非靜態全域性變數的作用域是整個源程式,當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是...

static 變數 全域性變數

一 static 變數 static變數大致分為三種用法 1.用於區域性變數中,成為靜態區域性變數.靜態區域性變數有兩個用法,記憶功能和全域性生存期.2.用於全域性變數,主要作用是限制此全域性變數被其他的檔案呼叫.3.用於類中的成員.表示這個成員是屬於這個類但是不屬於類中任意特定物件 1.靜態區域性...

static全域性變數與普通的全域性變數

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