我希望在初始化静态字段 (#B) 之前调用全局变量的初始化 (#A)。
目前,一些静态字段在全局变量之前被初始化。
GridUtil.h
class GridUtil{
static Vec4* bPtr_; //will be filled
static void initGridCalculationCache();
static class _init //helper class
{
public:
_init() {
static_iniAll();
}
} _initializer;
}
GridUtil.cpp
#include "GridUtil.h"
GridUtil::_init GridUtil::_initializer;// (Edit: This line is just added, thank Dietmar Kühl.)
Vec4 b[24]; //#A executed 3rd : No, this should be the first.
Vec4* GridUtil::bPtr_=b; //#B executed 1st
void GridUtil::initGridCalculationCache() {
//.... fill GridUtil::bPtr_ using complex computation //#C executed 2nd
}
结果
从调试来看,以上代码的执行顺序是:-
B->C->A
但是我想要:-
A->B->C
我注意到如果“Vec4”换成“int”,执行顺序会是:-
A->B->C
目标是使用将自动调用的静态函数 (initGridCalculationCache) 设置数组 (bPtr_) 中元素的值(由类 _init 帮助)。
如果不可能,正确的做法是什么?
最佳答案
按优先顺序排列的四个明显的解决方案是:
- 不要以全局或
静态
成员变量开始!这些往往会产生大量问题,在使用并发的系统中更是如此。 - 使用
constexpr
对象,因为这些对象在编译期间被初始化。显然,对可以执行的操作有一些限制,但编译器会验证对象是否以正确的顺序初始化。 - 在翻译单元内,具有静态实时时间的对象从上到下初始化。也就是说,如果变量定义可以达到所需的顺序,则使用正确的顺序。然而,没有可移植的方法来跨翻译单元对变量初始化进行排序。
- 当来自不同翻译单元的对象之间的初始化存在依赖性时,可以使用返回引用的函数局部
static
对象来保证正确的顺序:这些对象将在第一次访问时构建。<
关于c++ - 强制在某个静态字段之前初始化全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38889717/