确保全局变量的初始化顺序正确
Guaranteeing correct initialization order of global variables
我已经实现了表示枚举可能性的自定义类,类似于本文:
// 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
)来初始化另一个翻译单元中的全局变量时,我遇到了问题。我知道发生这种情况是因为没有定义哪个翻译单元全局变量首先初始化。如何解决初始化排序问题?
我能想到的唯一解决方案是使用漂亮的计数器。但我不知道如何在不影响枚举类语法的情况下使用它。我正在考虑在Color
中添加set()
方法。然后我可以在一个漂亮的类似计数器的初始化器中调用这个方法:
// 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中(如果你能负担得起的话),你可以使用扩展的常量表达式功能:
class Color {
public:
static constexpr const Color Red;
static constexpr const Color Green;
static constexpr const Color Blue;
private:
constexpr explicit Color(int code);
//...
};
// Color.cpp:
constexpr Color Color::Red(1);
constexpr Color Color::Green(2);
constexpr Color Color::Blue(3);
//...
首先不要使用全局对象。相反,使用以下功能:
class Color {
public:
static const Color &Red() {
static const Color c( 1 );
return c;
}
static const Color &Green() {
static const Color c( 2 );
return c;
}
static const Color &Blue() {
static const Color c( 3 );
return c;
}
private:
explicit Color(int code);
//...
};
现在,您可以使用这些函数来初始化其他对象;调用它们将确保调用Color
对象的构造函数。
由于您的Colour对象是轻量级的,因此可以只使用静态函数。
class Color {
public:
static Color Red() { return Color(1); }
static Color Green() { return Color(2); }
static Color Blue() { return Color( 3 ); }
private:
explicit Color(int code);
};
唯一的问题是不能将这些对象传递给期望指针或非常量引用的函数(但在这种情况下,非常量引用可能毫无意义)。
相关文章:
- lambda 作为接受其他参数的参数的初始化顺序
- 大括号或等于初始值设定项初始化顺序
- 类内初始化与构造函数初始化列表的顺序
- C++ 模板中的静态常量初始化顺序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 线程局部变量的初始化顺序
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 类静态变量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 解析 CRTP 初始化顺序
- 初始化相等C++的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 使用constexpr的全局初始化顺序
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 结构化绑定的标识符是否按顺序初始化?
- c++中的求值顺序初始化数组
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的