2010-12-15 97 views
4

我有一個名爲Component的基類,其中有許多類派生自它。我希望每個類都有一個與它相關的整數(只要它們從0開始並且是連續的,哪個組件獲得什麼值並不重要)。我不知道如何直接做到這一點,所以在相同的文件中Component我增加了以下內容:靜態變量將其值自己重置爲0顯然

template <typename T> 
class ComponentIdentifier 
{ 
public: 
    static unsigned int cid; 
}; 

static unsigned int CIDCounter = 0; 
template <typename T> unsigned int ComponentIdentifier<T> = CIDCounter++; 

template <typename T> unsigned int ComponentID() 
{ 
    return ComponentIdentifier<T>::cid; 
} 

unsigned int ComponentCount(); // Defined in .cpp file, just returns CIDCounter 

現在我測試的的ComponentID()函數,它似乎很好地工作。我試過ComponentID的每個組件類都返回一個不同的整數,就像我期望的那樣。然而,每當我打電話給ComponentCount時,我得到0.

例如,如果我有下面的代碼行:

std::cout << ComponentID<AAA>() << std::endl; 
std::cout << ComponentID<BBB>() << std::endl; 
std::cout << ComponentID<CCC>() << std::endl; 
std::cout << ComponentCount() << std::endl; 

那麼我的輸出是:

0 
1 
2 
0 

我懷疑發生的事情是,CIDCounter被設置爲0它用於設置CID各的之後再次組件,但我不確定,而且看起來很奇怪。有沒有辦法做我想做的或者我瘋了,這整個計劃註定要失敗?

回答

9

您已經聲明瞭標識爲靜態:

static unsigned int CIDCounter = 0; 

這意味着每個編譯單元都會有自己的變量的副本。相反,你應該把它聲明爲在頭文件的extern:

extern unsigned int CIDCounter; 

並初始化它的實現文件

unsigned int CIDCounter = 0; 

人們應該注意到,如果沒有適當的鎖,這將不會是線程安全的。

爲了進一步闡明:

在本上下文中static關鍵字意味着該變量或函數被限制在當前編譯單元(通常是CPP文件)。我猜你有一個main.cppidcounter.cpp - 所以現在我們有兩個變量(每個編譯單元一個)main_CIDCounteridcounter_CIDCounter(變量名僅用於解釋!)。

當您在main.cpp中執行測試代碼時,模板函數會看到main_CIDCounter,因爲這是當前編譯單元,您會得到預期的1,2,3。但是,當您撥打ComponentCount()時,將使用來自idcounter.cpp的代碼,並且該代碼看到idcounter_CIDCounter - 該代碼根本未被修改。如果您有其他編譯單元,您會看到類似的行爲,其中每個cpp文件似乎都維護着自己的ID計數器。

我所描述的修復只是在idcounter.cpp中只有CIDCounter的一個副本,並在所有其他編譯單元中將其聲明爲外部。

+0

謝謝,這是做到了。 – Alex 2010-12-15 09:20:33