I have implemented custom class representing an enumeration possibilities similarily to 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);
//...
Now I have problem when I want to use instances of Color
e.g.: Color::Red
to initialize a global variable in another translation unit. I understand that it happens because it is not defined which translation unit global variables are initialized first. How the initialization ordering problem could be solved?
The only solution that I can think of is using nifty counter. But I am not able find out, how to use it without affecting syntax of the enumeration class. I was thinking about adding set()
method into Color
. Then I could call this method in a nifty counter like initializer:
// 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;
But the problem I see here is that the set
method could be called on object that is not yet constructed. Is that OK or is the behavior undefined? How to better solve the problem of undefined initialization order?