静态初始化顺序失败
在他的Thinking in C++"(第 10 章)中,Eckel 描述了一种由 Jerry Schwarz 首创的技术来解决这场惨败.他说如果我们想将 x 初始化为 100 并将 y 初始化为 200 并在所有翻译单元之间共享它们,我们会创建一个如下所示的 Initializer.h:>
In his "Thinking in C++" (Chapter 10) Eckel describes a technique that was pioneered by Jerry Schwarz to solve the fiasco. He says that if we want to initialize x to 100 and y to 200 and share them among all translation units, we create an Initializer.h that looks like this:
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;
并且 Eckel 说静态初始化(在实现文件中)将强制所有这些值为零".
and Eckel says that "static initialization (in implementation file) will force all these values to zero".
让我考虑以下情况:编译器在包含该标头的其他文件之后处理实现文件(这意味着 x 和 y 已在该其他文件中设置为 100 和 200).编译器看到int x
,它会怎么做?它是否会将 x 和 y 设置为零以消除初始化和先前文件中所有可能的更改?但如果是这样,那么 initCount
也将被设置为零,从而破坏整个技术.
Let me consider the following case: the compiler processes the implementation file after some other file with that header included (it means that x and y have been already set to 100 and 200 in that other file). The compiler sees int x
, so what will it do? Will it set x and y to zero eliminating initialization and all possible changes in previous files? But if it does, then initCount
will also be set to zero, breaking down the whole technique.
推荐答案
但如果它是真的,并且编译器在另一个文件之后处理实现文件,那么它会将 x 和 y 设置为零以消除初始化和先前文件中所有可能的更改?
But if it is true, and the compiler handles the implementation file after some another file, than it will set x and y to zero eliminating initialization and all possible changes in previous files?
我不确定你的意思.如果在其他文件中定义了 x
和 y
,那么您就会发生链接器冲突,并且程序根本无法编译.
I'm not sure what you mean by this. If x
and y
are defined in other files, then you have a linker clash and the program simply won't compile.
如果 x
、y
和最重要的 Initializer::initCount
以这种方式实现,它们将在程序;它们实际上是全局的,将在程序开始时初始化为 0
,之前 任何 Initializer
被构造(由于包含声明一个 static
该类的实例).static Initializer
的每个构造都会首先检查是否由于 if (initCount++ == 0)
等原因构造了任何其他 Initializer
.
If x
, y
and most importantly Initializer::initCount
are implemented in this way, there will be unique instances of them in the program; they are effectively global and will be initialized to 0
at program start, before any Initializer
is constructed (due to inclusion of the header declaring a static
instance of that class). Each construction of a static Initializer
will first check whether any other Initializer
s have been constructed due to the if (initCount++ == 0)
etc.
要运行的第一个 Initializer
构造函数(仍在进入 main
之前)将因此设置所有三个值.
The first Initializer
ctor to run (still before entering main
) will thus set all three values.
相关文章