1. 初始化時機
全局變量、文件域中的靜態變量、類中的成員靜態變量在main函數執行前初始化;局部變量中的靜態變量在第一次調用時初始化。
C和C++的區別:局部靜態變量:
在C語言中是編譯期初始化並分配內存,故不能用變量給靜態局部變量賦值,只能用常量。
在C++中是第一次執行時初始化,因為C++引入了對象的概念,對象一般需要構造函數,無法簡單的分配內存,故可以用變量賦值,並且在第一次使用時初始化。
初始化又分為靜態和動態:
靜態初始化:
針對用常量來對全局變量進行初始化的情況,這個變量是簡單的內置類型(不包括含構造函數的復雜類,歸屬於下一項)。例如這里的a變量。
int a = 3; class A{ };
在程序加載過程中完成。
根據變量是否設置初值分別放於data segment段(設置初值)和bss段(未設置初值)
動態初始化(運行期)(main函數前,局部靜態變量除外):
1. 需要經過函數調用來完成的初始化。例如這里的a變量。
int a = foo()
2. 復雜類型的初始化。需要調用構造函數。例如這里的aa變量。
Class A{
A(){}
}
A aa;
靜態初始化的時機是先於動態初始化的。
1)類的靜態成員變量聲明和定義
使用過類中的靜態成員變量的伙伴都發現了,在類中定義的靜態成員變量,還必須要在類外定義下才可以使用,否則會編譯報錯。
那么為什么會出現這種情況呢?
靜態成員變量不屬於任何一個對象,對象的數據中不應該包含靜態成員的數據。所以在定義類的時候不會給靜態變量分配內存只是聲明,因此就要在其他地方分配即定義。
定義與聲明的區別:
聲明:只是向程序表面變量的類型和名字。
定義:為變量分配內存,也可以順便初始化。程序中變量有且只有一個定義(更能說明為什么要在類外再定義下類的靜態成員變量了)。
2. 初始化順序
對於編譯單元(同一個文件)的全局變量來講,初始化順序跟聲明的順序一致。銷毀順序則相反。
對於不同編譯單元的全局變量,初始化順序不確定。對於不同編譯單元的全局變量互相引用的情況應避免。
3. 解決不同文件相互引用全局變量初始化順序不確定問題
1)可以通過函數調用,引用的時候不直接引用全局變量,而是放在一個函數中。函數中的全局變量在調用時初始化。
int get_a() {
static int a = 5;
return a; } int get_b() {
static int b = get_a();
return b; }
