Singleton的静态初始化顺序
Static Initialization Order for Singletons
所以我读到零初始化将初始化:
在任何其他初始化之前,具有静态或线程本地存储持续时间的每个命名变量都不需要进行恒定初始化
我使用的是带有传统私有构造函数的Singleton和静态公共方法,其中有一个本地静态Singleton对象,该方法将返回该对象。
我的问题是,该类还有一个静态vector
,它是零初始化的,并且它似乎在单例之后被初始化,这意味着我无法与它交互。有什么东西控制这个初始化顺序吗?还是只是定义了实现?
这是我的代码的简化:
class Foo {
Foo(){ s_vec.push_back(13); }
public:
static Foo& Get() {
static Foo singleton;
return singleton;
}
int Front() const { return s_vec.front(); }
static vector<int> s_vec;
};
vector<int> Foo::s_vec;
我遇到这个问题是因为在代码的其他地方,我正在初始化这样的静态全局变量,但没有得到13:static const auto element = Foo.Get().Front()
全局变量的构造函数在main开始之前执行,但没有指定跨编译单元的顺序。
您的示例中的Foo
构造函数只应在调用Foo::Get
时调用。如果第一次调用它是在main
中,则静态向量将已初始化。
一种情况是,当您在另一个全局对象的初始化代码中调用Foo::Get
时,尤其是当代码位于另一个编译单元中时,您可能会遇到所描述的竞争。
但在这里这样的简单测试中,向量应该总是首先初始化,并且不会有可能的竞争:
class Foo {
Foo() = default;
public:
static Foo& Get() {
static Foo singleton;
return singleton;
}
static vector<int> s_vec;
};
vector<int> Foo::s_vec; // will be initialized before main
int main() {
Foo::Get(); // --> triggers constructor call Foo::Foo
return 0;
}
(我假设Foo::Get
是singleton中的静态成员,否则您无法实例化它。但它在概念上没有什么区别。)
有问题的场景可能是这样的:
// other file
struct Bar {
Bar() { Foo::Get(); }
};
Bar bar; // global object
您无法控制Foo::s_vec
(在第一个编译单元中)和bar
(在第二个编译单元)的初始化顺序。
相关文章:
- lambda 作为接受其他参数的参数的初始化顺序
- 大括号或等于初始值设定项初始化顺序
- 类内初始化与构造函数初始化列表的顺序
- C++ 模板中的静态常量初始化顺序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 线程局部变量的初始化顺序
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 类静态变量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 解析 CRTP 初始化顺序
- 初始化相等C++的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 使用constexpr的全局初始化顺序
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 结构化绑定的标识符是否按顺序初始化?
- c++中的求值顺序初始化数组
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的