2011-06-05 119 views
3

靜態變量具有文件內部的範圍僅在那裏它們被被聲明,如示於以下代碼:靜態成員變量文件範圍

file1-

static int a; 

file2-

extern int a; 

這會導致鏈接錯誤,因爲靜態變量a僅在file1中具有範圍。但我很困惑與下面的代碼:

file2-

#include "file1" 
extern int a; 

這不會給任何連接錯誤。那麼它意味着編譯器引用了在file1中聲明的「a」。但是當你調試時,你會發現變量「a」的地址在file1和file2中是不同的。編譯器是否在file2中創建另一個全局變量「a」?

完整的代碼 -

文件temp1.h -

static int w = 9; 

class temp1 
{ 
public: 
    temp1(void); 
public: 
    ~temp1(void); 

    void func(); 

}; 

........................ .. CPP ...............

temp1::temp1(void) 
{ 
    int e =w; 
} 

temp1::~temp1(void) 
{ 
} 
void temp1::func() 
{ 
} 

............................ ........... file2-

#include "temp1.h" 

extern int w; 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    w = 12; 

    temp1 obj; 
    return 0; 
} 

在這裏,當我調試和檢查temp1構造函數和file2中的值和adrress是不同的。

+0

除非'temp1.h'包含自身,否則該代碼不完整(或可能不正確)。你能顯示'temp1.h'的內容嗎? – 2011-06-05 14:03:29

+0

發佈編輯,我想我的回答完全回答你的問題。在兩個翻譯單元中,'w'具有_internal linkage_,因爲頭文件中包含的'w'是'static int w = 9;'聲明的第一個聲明。這意味着兩個翻譯單元都有自己獨特的獨立「w」。 – 2011-06-05 14:35:26

+0

所以這意味着第二個翻譯單元也定義變量w,即使它是外部的(因爲它不會導致重新定義,因爲第一個定義是翻譯單元1中的內部連接)? – 2011-06-05 15:13:23

回答

3

文件1:

static int a; 

文件2:

extern int a; 

這裏有參考兩個變量。首先是內部聯動file1中的一個變量的聲明和定義;第二個是僅有一個變量的聲明外部鏈接file2。這不一定會導致錯誤;在一些翻譯單位中使用具有外部連接的變量以及由其他翻譯單位使用內部連接的同名變量是完全合法的。任何鏈接錯誤只會在file2中使用afile2中的a或程序中的任何其他翻譯單元沒有定義。

#include "file1" 
extern int a; 

在這個例子中,你已經將兩個文件組合成一個單一的翻譯單元。變量a首先在file中用內部鏈接進行聲明和定義,因爲static,第二個只是重新聲明,它不會改變以前的鏈接。在這種情況下,第二個聲明是多餘的。如果您仍然單獨編譯這兩個文件以及從file2包括file1,那麼每個翻譯單元(file1file1 + file2)將具有其自己的獨特變量,稱爲a

需要注意的是,如果你使用過之後static int a;extern int a;那麼這將是一個編譯錯誤,因爲第一個聲明將宣佈a外部鏈接如果沒有事先聲明是可見的,那麼第二個聲明和定義會導致錯誤,因爲static int a;暗示的鏈接會與先前的聲明發生衝突。

+0

現在這對我有意義。謝謝Charles的澄清。 – 2011-06-06 14:32:15

7

staticextern不符合文件做,他們與翻譯單元做。請記住,當你的某些東西,預處理器正在有效地進行復制和粘貼。 static等指的是該過程的結果,該過程是翻譯單元。

所以在第二個例子中,只有一個翻譯單元。所以只有一個變量a[但要注意,做這種方式被認爲是非常不好的風格。]

+0

是的,這是一個翻譯單元。但爲什麼varaibale「a」的地址在兩個文件中都不同? – 2011-06-05 13:39:47

+0

@Ghanshyam:我想你必須編輯你的問題來顯示一個*完整的*,*可編譯的*例子來展示你的意思。 – 2011-06-05 13:41:02

+0

下面是代碼 – 2011-06-05 13:53:35