埃克尔(Eckel)在他的“C++思维”(第10章)中描述了杰里·施瓦茨(Jerry Schwarz)开创的解决惨败的技术。
他说,如果我们要将x初始化为100,将y初始化为200,并在所有翻译单元之间共享它们,则我们将创建一个Initializer.h,如下所示:

extern int x;
extern int y;
class Initializer {
   static int initCount;
   // if (initCount++ == 0) x = 100 & y = 200
   /* ... */
};
static Initializer init;

在执行文件中,我们有
#include "Initializer.h"
int x;
int y;
int Initializer::initCount;

埃克尔说:“静态初始化(在实现文件中)会将所有这些值强制为零”。

让我考虑以下情况:编译器在包含该 header 的其他某个文件之后处理实现文件(这意味着x和y在该其他文件中已经分别设置为100和200)。编译器看到int x,那么它将做什么?它将x和y设置为零以消除初始化和先前文件中的所有可能更改吗?但是,如果这样做,initCount也将设置为零,从而破坏了整个技术。

最佳答案



我不确定您的意思是什么。如果在其他文件中定义了xy,则您将发生链接器冲突,并且该程序将根本无法编译。

如果以这种方式实现xy和最重要的Initializer::initCount,则程序中将存在它们的唯一实例;它们实际上是全局的,并且在构造任何0之前(由于包含了声明该类的Initializer实例的 header ),将在程序启动时初始化为staticstatic Initializer的每种构造都会首先检查是否由于Initializer等而构造了其他if (initCount++ == 0)

因此,要运行的第一个Initializer ctor(仍在输入main之前)将设置所有三个值。

关于c++ - 静态初始化顺序惨败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5299095/

10-16 19:09