2010-11-15 54 views
3

我在頭文件中定義了下面的結構和結構對象,如下所示:爲什麼錯誤LINK2005:當我將對象聲明爲靜態時,對象已定義的錯誤消失

struct STConfigurationDetails 
{ 
    bool bAutoStart; 
    bool bAutoLog; 
    bool bAutoScan; 
    bool bAutoMount; 
    bool bAutoOpen; 
    bool bAutoDetectLast; 
}; 

struct STConfigurationDetails g_objConfigurationDetails ; 

在頭文件中,我自己擁有使用g_objConfigurationDetails的方法和方法體。當我將頭文件包含到另一個cpp文件並調用該方法時,這工作正常。但是當我將頭文件添加到另一個cpp文件時,我得到了錯誤:

Error 1 error LNK2005: "struct STConfigurationDetails g_objConfigurationDetails" ([email protected]@[email protected]@A) already defined in NDSClientDlg.obj NDSConnectDlg.obj NDSClient

Error 2 fatal error LNK1169: one or more multiply defined symbols found d:\FromClearCase\Development_view\NDS_11152010\exe\Debug\NDSClient.exe 1 NDSClient

在搜索了幾個線程後,我發現我必須將我的對象聲明爲靜態並且它已經解決了。但我想知道爲什麼在我只在te頭文件中創建實例時出現多個實例錯誤。

這是因爲我的頭文件有一個全局變量,它被包含在多個CPP中?

回答

4

添加static可能會解決您的鏈接問題,但會給您一個更大的問題。該變量不再是全局變量,並且在每個使用它的CPP文件中具有不同的值。您需要在頭文件中聲明它爲extern,然後在一個CPP文件中再次聲明它。

當您使用static時,表示該變量將完全位於當前CPP文件的本地,並且不會暴露給其他文件。這就是爲什麼鏈接器不再在意在另一個具有相同名稱的文件中是否存在另一個靜態變量。它們不是同一個變量。

如果您想要一個真正的全局變量,它必須在一個CPP文件中聲明,並且只有它的原型(與extern)應該位於將與其他CPP文件共享的頭文件中。這完全像函數 - 在一個文件中聲明,其餘的原型。對於功能,你只是不提供一個機構。對於變量,您使用extern

3

如果你仔細想想,這很容易。該變量在頭文件中定義,因此包含該頭文件的每個.cpp文件都會獲得自己的變量副本。現在,如果您不添加static,則所有.cpp文件都會通過外部鏈接獲取相同的變量,並在編譯時發生錯誤。

當您添加static時,每個.cpp仍然具有與來自相同定義的其他變量無關的變量,但它們不再具有外部鏈接,因此鏈接器不會發出錯誤。

但是不要忘記,每個變量都是一個單獨的變量,它佔用內存並且具有構建/銷燬的開銷,如果代碼期望只有一個變量在所有.cpp文件中共享,您將會收到意想不到的行爲。

相關問題