我已經實現表示枚舉可能性相若方式來this article自定義類:保障全局變量的正確初始化順序
// Color.h
class Color {
public:
static const Color Red;
static const Color Green;
static const Color Blue;
//...
private:
explicit Color(int code);
//...
int code;
static std::set<Color> colors;
};
// Color.cpp:
const Color Color::Red(1);
const Color Color::Green(2);
const Color Color::Blue(3);
//...
現在我有問題時,我想使用的實例Color
例如:Color::Red
初始化的全局變量在另一個翻譯單位。我知道這是因爲它沒有定義哪個翻譯單元全局變量是首先被初始化的。初始化排序問題如何解決?
我能想到的唯一解決方案是使用漂亮的計數器。但是我無法知道如何在不影響枚舉類語法的情況下使用它。我正在考慮將set()
方法加入Color
。然後,我可以像初始化一個漂亮的反調用這個方法:
// Color.h
class Color {
public:
void set(int code);
//...
private:
Color() { /* empty */}
//...
};
static class ColorInitializer {
ColorInitializer() {
static bool initialized = false;
if(initialized)
return;
Color::Red.set(1);
Color::Green.set(1);
Color::Blue.set(1);
initialized = true;
}
} colorInitializer;
// Color.cpp
const Color Color::Red;
const Color Color::Green;
const Color Color::Blue;
但我看到這裏的問題是,set
方法可以在一個尚未構造的對象調用。這是好的還是行爲未定義?如何更好地解決未定義初始化順序的問題?
我沒有使用C++ 11的經驗,但我嚴重懷疑'ColorInitializer'的整個方法並不好。使用'{...}'等進行初始化可以更好地進行調查,等等。您爲第一個代碼示例獲取什麼錯誤? – 2012-07-12 13:17:46
@Kirill Kobelev:我沒有收到任何編譯錯誤,它只是一個未定義的行爲。變量在使用時可能會被初始化,也可能不會被初始化。 – 2012-07-12 13:21:06
然後我會懷疑這種行爲與你的特定班級沒有關係。嘗試隔離問題。鏈接器有問題嗎? – 2012-07-12 13:25:42