是否可以保证静态初始化不会覆盖显式初始化的值

Are there any guarantees that static initialization will not overwrite the value from explicit initialization?

本文关键字:初始化 覆盖 静态 是否      更新时间:2023-10-16

假设我有以下两个变量,它们都是静态初始化的,并且它们位于不同的编译单元中。

Foo.cc

Foo foo;

Bar.cc

Bar bar;

假设,通常bar是在foo之后静态初始化的。

如果foo的构造函数被写入bar的值,那么bar的后续静态初始化是否有可能覆盖foo? 写入的值

也就是说,假设Bar有第二个接受字符串的构造函数,foo的构造函数如下所示:

Foo::Foo() {
   bar = Bar("Hello World");
    /// do other stuff to make a Foo
}

bar的静态初始化是否有可能在foo之后运行,并覆盖由foo的构造函数编写的bar的值?

是的,动态初始化(这是调用静态构造函数时发生的情况)可以以任何顺序发生。

如果静态对象需要相互依赖,最好根据需要动态分配它们,并保护初始化,使其只发生一次,类似于singleton模式。

正如Scott Meyers所说:

[…]在不同转换单元中定义的非局部静态对象的初始化的相对顺序是未定义的。[…]

和:

幸运的是,一个小小的设计更改就完全消除了这个问题。所要做的就是将每个非本地静态对象移动到其自己的函数中,在那里它被声明为静态。这些函数返回对它们所包含对象的引用。然后客户端调用函数,而不是引用对象。换句话说,非局部静态对象被局部静态对象所取代。(设计模式的爱好者会认识到这是Singleton模式的常见实现。)

作为这项工作的一个例子,可以看:http://www.parashift.com/c++-faq/static-init-order-on-first-use-members.html