【发布时间】:2012-07-12 13:08:29
【问题描述】:
我已经实现了代表枚举可能性的自定义类,类似于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的整个方法并不好。更好地调查使用{...}等进行初始化。您的第一个代码示例遇到什么错误? -
@Kirill Kobelev:我没有收到任何编译错误,这只是一个未定义的行为。变量在使用时可能会或可能不会被初始化。
-
那么我怀疑这种行为与您的特定班级无关。尝试隔离问题。链接器有问题?
-
保证正确初始化顺序的最简单方法是不使用任何全局变量。
-
@Frerich Raabe:如您所见,我的接受率相当高。这意味着我知道如何接受答案。
标签: c++