在单个翻译单元中考虑以下代码:
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];
答案 0 :(得分:6)
int C::data[200]
零初始化,这意味着静态初始化。静态初始化在动态初始化之前。由于C::Init::Init()
不是常量表达式,因此动态初始化C::i
, C::data
之后必须。
详见3.6.2。
盗版报价:
具有静态存储持续时间的变量[...]应在任何其他初始化发生之前进行零初始化。 [...]一起,零初始化和常量初始化称为静态初始化;所有其他初始化是动态初始化。在进行任何动态初始化之前,应执行静态初始化。
答案 1 :(得分:0)
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];
答案 2 :(得分:0)
C :: i总是在C :: data之后初始化,无论顺序如何 两者的定义?
如果订单在同一编辑中定义,则保证订单 单位,否则不是。
这个解决方案一次是计算静态数据最优雅的吗?
没有。如果你真的必须让它静态,那么更好的方法(并防止可能的静态初始化命令惨败)是这样做的:
struct someDataStr
{
int data[200];
};
someDataStr& AccessData()
{
static someDataStr *ptr = NULL;
if ( NULL == ptr )
{
ptr = new someDataStr;
// initialize value
}
return *ptr;
}
如果它不必是静态的,那么使用依赖注入,并使用它将包含数据的对象传递给所有类。