2011-11-25 92 views
12

在C和C++中,所有靜態變量默認初始化爲零。爲什麼要在C++中初始化靜態類變量?

這不是靜態類數據成員的情況。這是爲什麼?

#include <iostream> 
using namespace std; 

int var; 

class MyClass 
{ 
public: 
    static int classVar; 
}; 
int MyClass::classVar = 0; // Why I have to init it here? 

int main(void) 
{ 
    cout << ::var << endl;   // this is initalized to ZERO by default 
    static int var; 
    cout << var << endl;   // and this also is initalized to Zero 
    cout << MyClass::classVar << endl; 

    return 0; 
} 
+0

您不確定** var **是否已初始化爲0.可能,有時很可能,但不確定。 –

+3

@AlessandroPezzato:實際上,在執行動態初始化之前,標準顯式地爲所有全局變量清零內存......除了受字面值影響的內置函數,我認爲可以直接影響(在因爲它是不可觀測的。 –

回答

21

類範圍,

int MyClass::classVar = 0; // Why I have to init it here? 

定義

static int classVar; 

聲明,即。承諾該變量將被定義爲某處:您必須定義恰好一次您聲明的變量。

基本原理是類聲明可能會包含在多個源文件中。它的一部分是一個定義,它會發生倍增:這是錯誤的(例外是內聯[成員]函數)。

注意的是,根據值初始化規則,你可以用

int MyClass::classVar; // Zero-initialized ! 

的定義相處。

在命名空間內聲明的變量定義太(除非他們是extern合格):

int var; 

是一個聲明,以及一個定義:如果你把它放到頭並將其包含在多個翻譯單位,你有一個錯誤(「乘法定義的符號」,或沿着這些線)。

[注意,在C++(而不是在C)中,如果上述varconst,它自動成爲static並且沒有擾定義規則違反應該它被放入一個乘法包含的頭。這又稍微偏離主題,但隨時問細節]認爲

+2

我不確定那是什麼被問到。我將其解讀爲「爲什麼我必須把'= 0;'在那裏?」 – Mat

+0

@Alexandre C .:如果你也解釋了爲什麼需要,這將是一件好事。 – Nawaz

+3

因此,如果你只需要零初始化,'int MyClass :: classVar;'應該已經足夠了。從來沒有嘗試過,但根據標準和刪除的答案,它實際上。 – zerm

2

您必須初始化您的靜態類數據變量,因爲您必須告訴編譯器它們的值是什麼。類不需要具有默認值的概念。

變量類型具有邏輯「零值」,對於int它是0,對於double 0.0,對於string「」等。相反,類不一定具有默認值。考慮一下,例如class Rectangle。它的零點值是多少? - 一個長方形的零方形或長方形的單位邊長?對於靜態變量,編譯器會要求您自己定義靜態變量必須具有的值,因爲不是每個數據類型都可以通過默認值進行初始化。

+1

我認爲你在這裏弄錯了:沒有什麼能夠阻止你定義一個靜態變量而不是初始化它,如果這個變量是一個類的實例,那麼它的構造函數將被調用 – qdii

+0

靜態變量必須被定義,構造函數不會初始化它。考慮下面的例子...如果「int test :: k;」將被評論,它將不會編譯。 class test { public: static int k; }; int test :: k; int main() { test t; cout << t.k; return 0; } – rakesh

+0

@victor是的,你是對的,謝謝你注意到我。問題是關於定義一個靜態變量,而不是它的初始化。 –