2011-09-08 23 views
2

我有一對類。其中一人有一組靜態常量uint32_t的的(下面的代碼是下調爲例):訪問多個源文件中的C++靜態類成員變量

class Foo { 
public: 
    static const uint32_t BAZ; 
    void RunMe(void); 
}; 
class Bar { 
public: 
    void RunMeAlso(void); 
}; 

我做的每CPP文件一類的平常的事情,因爲實際的類是相當可觀,但我遇到了一個問題。 Foo::RunMe()Bar::RunMeAlso()都訪問值Foo::BAZ

我已經在foo.cpp中定義了const uint32_t Foo::BAZ = 1;,但是在VS2010中bar.cpp(在switch語句中它被用作一個case標籤)中遇到了編譯錯誤(這個代碼需要是可移植的,但我還沒有用gcc檢查過它)。這兩個頭文件都包含在這兩個源文件中......並嘗試在bar.cpp中放入某種外部引用,以告訴編譯器它位於不同的翻譯單元中並不能解決它(創建更多編譯錯誤)...當然,我在這類主題上找到的所有例子都是針對單個類/文件的簡單情況,其中有人不知道/忘記了除了聲明之外還使用了定義。

有沒有人想過如何解決這個問題? (我寧願不必使用枚舉,但會如果這是唯一的選擇,因爲我敢肯定,這將編譯)

TIA,

-J

+0

你得到了什麼確切的錯誤? – Drakosha

+0

我想你應該面對鏈接器錯誤而不是編譯器錯誤。你能發佈錯誤嗎? – iammilind

+0

bar.cpp中的代碼如何引用Foo :: BAZ? – kennbrodhagen

回答

3

案例標籤必須是編譯器常量。一個靜態成員變量不是一個編譯器常量,除非它是常量並且在聲明中用一個常量表達式進行初始化。

所以:

  • 聲明它在頭static const uint32_t BAZ = 1;;或
  • 使用if而不是switch

順便說一句,通常閱讀實際的錯誤信息是很有幫助的。併發布它,如果你要問它...

+0

我會記住下次發佈錯誤消息,但你說得對:它是關於非常量情況標籤。我會轉換爲if-else的東西,因爲大多數時候我實際上訪問這些常量,switch語句只有2或3個case語句。謝謝,rodrigo! –

+0

實際上,爲了完整起見,rodrigo是一個關於你所說的關於聲明的問題。我假設你的意思是我應該把'= 1'放到它聲明的類中,而不是將定義移到標題中(因爲這會導致鏈接器錯誤,對嗎?) –

+0

當然可以。一個簡單類型的靜態const成員變量,用declare_中的一個常量表達式進行初始化,被認爲是一個編譯器常量,非常像枚舉常量或全局常量。如果這些條件中的任何一個都不符合,那麼它就是一個變量,帶有外部鏈接和所有條件,並且不應將該定義放在標題中。 – rodrigo