我已经实现表示枚举可能性相若方式来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