この記事と同様に、列挙の可能性を表すカスタム クラスを実装しました。
// 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
メソッドがまだ構築されていないオブジェクトで呼び出される可能性があることです。それはOKですか、それとも動作は未定義ですか? 未定義の初期化順序の問題をより適切に解決するには?