静态数据成员初始化顺序
Static data member initialization order
在一个翻译单元中考虑下面的代码:
class C {
private:
struct Init {
Init() {
/* compute data once here */
}
};
static const Init& i;
static int data[];
public:
/* interface for reading data */
};
const C::Init& C::i = Init();
int C::data[200];
- C::i总是在C::data之后初始化,不管两者定义的顺序如何?
- 这个解决方案是最优雅的计算静态数据一次?
int C::data[200]
is zero-initialized,即静态初始化。静态初始化在动态初始化之前。由于C::Init::Init()
不是一个常量表达式,所以C::i
是动态初始化的,必须在 C::data
之后。
详情见3.6.2。
非法引用:
具有静态存储时间的变量[…]在进行任何其他初始化之前,应该进行零初始化。[…零初始化和常量初始化一起称为静态初始化;其他所有初始化都是动态初始化。静态初始化应在任何动态初始化之前执行。
C::data
在这里没有初始化,所以顺序不重要。
较短的解决方案是使用静态函数和虚拟变量:
class C {
private:
static void Init() {
/* compute data once here */
}
static bool data_init_helper;
static int data[];
public:
/* interface for reading data */
};
bool C::data_init_helper = (C::Init(), false);
int C::data[200];
是否C::i总是在C::data之后初始化,无论C::data的顺序如何两者的定义?
如果它们在同一编译中定义,则保证顺序
这个解决方案是最优雅的计算静态数据一次?
。如果您真的必须让它保持静态,那么一个更好的方法(并防止可能的静态初始化顺序惨败)是这样做:
struct someDataStr
{
int data[200];
};
someDataStr& AccessData()
{
static someDataStr *ptr = NULL;
if ( NULL == ptr )
{
ptr = new someDataStr;
// initialize value
}
return *ptr;
}
如果它不是静态的,那么使用依赖注入,并将包含数据的对象传递给使用它的所有类。
相关文章:
- lambda 作为接受其他参数的参数的初始化顺序
- 大括号或等于初始值设定项初始化顺序
- 类内初始化与构造函数初始化列表的顺序
- C++ 模板中的静态常量初始化顺序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 线程局部变量的初始化顺序
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 类静态变量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 解析 CRTP 初始化顺序
- 初始化相等C++的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 使用constexpr的全局初始化顺序
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 结构化绑定的标识符是否按顺序初始化?
- c++中的求值顺序初始化数组
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的