關於全域性、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 注意它與資料結構中的堆是...