關於C++類的靜態數據爲何必定要初始化

咱們知道C++類的靜態成員變量是須要初始化的,但爲何要初始化呢。函數

其實這句話「靜態成員變量是須要初始化的」是有必定問題的,應該說「靜態成員變量須要定義」纔是準確的,而不是初始化。spa

二者的區別在於:初始化是賦一個初始值,而定義是分配內存。code

靜態成員變量在類中僅僅是聲明,沒有定義,因此要在類的外面定義,其實是給靜態成員變量分配內存。
對象

能夠經過如下幾個例子更形象的說明這個問題:內存

//test.cpp 
#include <stdio.h> 
class A { 
    public: 
        static int a; //聲明但未定義
 }; 
int main() { 
    printf("%d", A::a);
    return 0;
}

編譯以上代碼會出現「對‘A::a’未定義的引用」錯誤。這是由於靜態成員變量a未定義,也就是尚未分配內存,顯然是不能夠訪問的。編譯器

再看以下例子:io

//test.cpp 
#include <stdio.h> 
class A { 
    public: 
        static int a; //聲明但未定義
 }; 
int A::a = 3; //定義了靜態成員變量,同時初始化。也能夠寫"int A:a;",即不給初值,一樣能夠經過編譯
int main() { 
    printf("%d", A::a);
    return 0;
}

這樣就對了,由於給a分配了內存,因此能夠訪問靜態成員變量a了。編譯

由於類中的靜態成員變量僅僅是聲明,暫時不需分配內存,因此咱們甚至能夠這樣寫代碼:class

//a.cpp
class B; //這裏咱們使用前置聲明,徹底不知道B是什麼樣子
class A {
    public:
        static B bb;//聲明瞭一個類型爲B的靜態成員,在這裏編譯器並未給bb分配內存。
                    //由於僅僅是聲明bb,因此編譯器並不須要知道B是什麼樣子以及要給其對應的對象分配多大的空間。
                    //因此使用前置聲明"class B"就能夠保證編譯經過。
};

使用命令"g++ -c -o a.o a.cpp"經過編譯。test

對於類來講,new一個類對象不只會分配內存,同時會調用構造函數進行初始化,因此類對象的定義和初始化老是關聯在一塊兒。

相關文章
相關標籤/搜索