2013-12-10 37 views
4

我們在一個類中聲明瞭一個static變量,並在該類之外初始化該變量,但我們在該函數中使用了該變量。爲什麼我們在類中聲明靜態變量以及在類外部定義?

有人告訴我爲什麼? 由於提前

+1

聲明和定義之間的C++有一個普遍的區別。在某些情況下,可以同時進行這兩種操作,但這不是其中之一。 – EJP

回答

5

我不知道,但我的猜測是,因爲裏面類成員變量只聲明。它們通過構造函數或其他成員函數進行初始化。

這發生在對象被實例化時。但是對於靜態成員,這些對象不需要實例化。因此,他們需要在課外進行一次初始化。

編輯:
其實這是沒有必要的初始化靜態變量,但它是必要的定義它們的類外爲他們分配內存。只有在它們的定義之後,它們才能被初始化,然後在程序中使用。

+0

1.此處輸出值i不是初始化值。 #include using namespace std; class sample { \t public: \t int i; }; int main() { \t sample s; \t cout << s.i; } 2.發生什麼事情,在類中聲明「static int i」.. 是不是分配內存? – Vicky

+0

在類中聲明時未分配內存。內存在實際定義在類之外時進行分配。 –

+0

在你提到的代碼中,當對象通過構造函數實例化時,變量i被初始化,而不是在類中聲明的時候。 –

1

使用標準機制將靜態變量分配在內存的不同部分。

如果他們在類的構造函數使用初始化,然後可能會有一些違反靜態變量分配的標準機制。

+0

什麼是'標準機制'?什麼'違規'?誰提到了構造函數? -1 – EJP

+1

通過標準機制,我指的是它們被分配到數據段(bss)中的事實,並且只能在其定義中初始化並且獨立於對象創建。另外一個普通的變量在類中使用構造函數(也是方法)進行初始化,所以人們會懷疑爲什麼不使用構造函數初始化,所以我提到了構造函數! –

+0

你還沒有回答我關於'侵犯'的問題; bss中的數據可以隨時初始化;數據段中分配數據的事實與構造函數或靜態無關。「這個答案只是一個沙拉。 – EJP

0

宣言在類中只聲明該範圍內的變量。 定義實際分配內存。

你使用它的類函數中,因爲它在該範圍內定義。對象創建時不會發生靜態變量初始化,而是在應用程序啓動時發生。

3

因爲靜態變量需要在某處分配一些存儲空間。

讓我們藉此例如:

struct Example 
{ 
    static int counter; 
    Example() { counter++; } 
}; 

,只要你想你可以創建許多Example情況,但只有將永遠是一個Example::counter變量。它基本上是一個變相的全球變量。但它住在哪裏?回到C++的早期階段,Stroustrup決定解決這個問題的方法是明確選擇一個翻譯單元(即.cpp文件)並在那裏聲明它,就像你將一個「真正的」全局變量一樣。所以,你需要做的是這樣

// Only in one .cpp file 
int Example::counter = 0; 

(當然,後來的模板被髮明的,弱符號和他們一起去,這可能已經解決了這個尷尬的混亂,但爲時已晚,屆時。)

1

由於靜態成員是在一個類的所有實例之間共享的,所以它們必須在唯一的一個地方定義。真的,它們是具有一些訪問限制的全局變量。

如果試圖在標題中定義它們,它們將每一個包括頭模塊中進行定義,並鏈接它找到的所有重複定義的過程中你會得到錯誤。

是的,這至少部分是從cfront開始的歷史問題;可以編寫一個編譯器來創建一種隱藏的「static_members_of_everything.cpp」並鏈接到該文件。但是,它會打破向後兼容性,這樣做沒有任何實際的好處。

相關問題