问题是在 C 中静态可以有不同的含义。我将尝试在以下段落中概述不同的情况。
如果一个变量是在函数之外定义的,它可以被文件中的所有函数使用。有时也称为“全局变量”。这意味着整个文件只有一个此变量的实例。变量的名称也存储在生成的 .OBJ 文件中。后者很重要,因为如果另一个文件也在函数之外定义了一个同名的变量,则链接器会假定在这两种情况下它是同一个变量,并将它们合并。
为了更清楚地说明这一点,最好将关键字“extern”添加到其中一个变量中。在这种情况下,我们说我们声明了变量,而不是定义它。这是编译器/链接器的一个额外信号,表明我们实际上想要引用在其他地方定义的全局变量。
如果你想定义一个全局变量,但又不想让它对其他文件可用,可以在前面加上关键字static。关键字 static 告诉编译器变量名不能存储在 .OBJ 文件中。这意味着两个 .C 文件具有以下行:
static long MyGlobalVariable;
每个人都有自己的变量。这两个变量都将被称为 MyGlobalVariable。
如果你在函数内部定义了一个变量,它就变成了一个局部变量。如果函数被调用,它就会存在,并在函数完成后再次消失。
在某些情况下,您希望在函数调用之间保留变量的值。您可以通过使用全局变量(而不是局部变量)来执行此操作,但随后该变量可用于文件中的所有函数,而您不一定想要。在这种情况下,您可以将关键字 static 放在变量之前,如下所示:
void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}
第一次调用函数时,MyLocalVariable 将被“创建”并初始化为值 0。在函数结束时,变量不会被销毁,而是被保留。所以下次调用这个函数时,变量的值会是 1,而不是 0。
在 C 中,将变量放在函数外部(作为全局变量)还是在函数内部将其定义为静态并不重要。唯一的区别是可以访问变量的位置。
在 C++ 中,情况完全不同。如果你写这个(在函数之外):
MyClass MyGlobalVariable;
MyGlobalVariable 将在应用程序开始时被构造(即:构造函数将被执行),甚至在调用 main 之前。但是,您无法真正控制所有全局变量的构造顺序。
所以如果另一个文件包含这个:
MyOtherClass MySecondGlobalVariable;
您无法确定是先构造 MyGlobalVariable 还是 MySecondGlobalVariable。如果其中一个的构造函数依赖于另一个的存在(构造),这可能会产生问题。
另一方面,如果你在函数中将变量定义为静态:
void MyFunction()
{
static MyClass MyStaticVariable;
}
那么 MyStaticVariable 将在第一次调用该函数时被构造。使用这种结构,您可以编写如下内容:
MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}
我们已经实现了一个单例,我们可以控制它的构建时间。我们第一次需要它时,它就被构建了。
说实话,这种方法是一种相当简单的方法,因为它可能会导致多线程应用程序出现问题。在这种情况下,还有其他技巧。