2011-02-18 42 views
7

靜態變量具有文件範圍。說我有兩個以下文件:
頭文件中的靜態變量

  • file1.h
  • file1.cpp
  • file2.h
  • file2.cpp

我已經聲明爲static變量都表示static int Var1頭文件。 main.cpp文件中包含file1.hfile2.h

我這樣做,因爲靜態變量將具有文件範圍,所以它不會相互衝突。 但編譯後,我發現它顯示衝突。

現在靜態變量的行爲如同extern變量。另一方面,如果我在.cpp文件中聲明瞭靜態變量,它編譯得很好。

我無法理解此行爲。

任何機構都可以解釋在這種情況下工作範圍的範圍和連接方式。

+0

相關的,請參見[不要在頭文件中定義一個未命名的名稱空間](https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+未命名+名稱空間+中的+ a +標題+文件) – jww 2018-02-20 16:47:14

回答

13

靜態變量對於編譯單元是本地的。編譯單元基本上是.cpp文件,其中.h文件的內容代替了每個#include指令。

現在,在編譯單元中,不能有兩個具有相同名稱的全局變量。這就是你的情況發生了什麼:main.cpp包括file1.hfile.h,並且兩個標題的每一個都定義了它自己的Var1

如果邏輯上這些是兩個不同的變量,給它們不同的名稱(或將它們放在不同的名稱空間中)。

如果這些是相同的變量,將其移動到一個單獨的頭文件,var1.h,並且包括var1.h來自file1.hfile2.h,不要忘記在var1.h#include guard

2

假設靜態變量static int Var1在兩個標題中都在全局範圍內並且在main.cpp中包含兩個標題。現在,首先預處理器將包含文件的內容複製到main.cpp。因爲在main.cppVar1在同一範圍內聲明瞭兩次,所以會出現多重聲明錯誤。 (即,通過預處理器複製從file1.h和另一個表格file2.h

每個源文件被單獨編譯。現在,當你在它們的源文件中分別聲明時,每個源文件都不知道另一個具有相同名稱的源文件中存在的另一個靜態變量。所以,編譯器不會報告錯誤。如果您希望在源文件之間共享變量,您可以將其標記爲extern。

8

靜態變量的翻譯單元範圍(通常爲.c.cpp文件),但文件的#include指令只是拷貝文本逐字,並且不會創建另一個翻譯單位。預處理之後,這樣的:

#include "file1.h" 
#include "file2.h" 

會變成這樣:

/* file1.h contents */ 
static int Var1; 

/* file2.h contents */ 
static int Var1; 

其中,如你所知,是無效的。

+0

我的瘦身是會有兩個編譯單元的。感謝您通過疑惑清除 – 2011-02-22 11:29:30