C + + 中的静态变量

我想知道头文件中的静态变量和类中声明的静态变量之间的区别是什么。在头文件中声明静态变量时,其作用域限于。H 文件或跨所有单位。中初始化静态变量。在类中声明的 cpp 文件,对吗?这意味着静态变量的作用域限制在2个编译单元内?

158839 次浏览

头文件中的静态变量:

'common.h'已经

static int zzz;

这个变量 'zzz'有内部链接(这个变量不能在其他翻译单元中访问)。每个包含 'common.h'的翻译单元都有自己的唯一对象,名称为 'zzz'

类中的静态变量:

类中的静态变量不是类的子对象的一部分。类的所有对象共享的静态数据成员只有一个副本。

$9.4.2/6-「 命名空间范围中的类具有外部 连结(3.5) 拥有静态数据成员。”

假设 'myclass.h'

struct myclass{
static int zzz;        // this is only a declaration
};

myclass.cpp已经

#include "myclass.h"


int myclass::zzz = 0           // this is a definition,
// should be done once and only once

"hisclass.cpp"已经

#include "myclass.h"


void f(){myclass::zzz = 2;}    // myclass::zzz is always the same in any
// translation unit

"ourclass.cpp"已经

#include "myclass.h"
void g(){myclass::zzz = 2;}    // myclass::zzz is always the same in any
// translation unit

因此,类静态成员不仅限于2个转换单元。它们只需要在任何一个翻译单元中定义一次。

注意: 使用“ static”来声明 不推荐使用 file 作用域变量,并且 未命名的命名空间是一种优越的 替补

在类之外的头文件中声明的静态变量在每个。包含头文件的 c 文件。这意味着具有相同名称的变量的单独副本可以在。包含头文件的 c 文件。

另一方面,静态类变量是 class-scoped,每个编译单元都可以使用相同的静态变量,这些编译单元包括包含带有静态变量的类的头。

对不起,当我回答你的问题时顺序错误,这样更容易理解。

当静态变量在头文件中声明时,它的作用域限制为.h 文件或所有单元。

没有所谓的“头文件作用域”。头文件将 包括转换为源文件。翻译单元是源文件 包括来自头文件的文本。无论您在头文件中写入什么,都会将 复制写入每个包含源文件的文件中。

因此,在头文件中声明的静态变量类似于每个源文件中的静态变量。

因为以这种方式声明变量 static意味着内部链接,所以每个翻译单元 #includeing 头文件都会得到它的 自己的个人变量(在翻译单元外不可见)。这通常不是你想要的。

我想知道头文件中的静态变量和类中声明的静态变量之间的区别是什么。

在类声明中,static表示类 分享的所有实例 this 成员变量; 也就是说,您可能有数百个这种类型的对象,但是每当这些对象中的一个引用 static(或“ class”)变量时,所有对象的值都是相同的。你可以把它想象成一个“全局类”。

通常静态变量是在.cpp 文件中初始化的,当在类中声明时,对吗?

是的,(只有 )翻译单元必须初始化 class 变量。

这意味着静态变量的作用域限制在2个编译单元内?

正如我所说:

  • 标头不是编译单元,
  • 根据上下文,static的意思完全不同。

全局 static将范围限制在翻译单元。类 static表示所有实例的全局。

希望这个能帮上忙。

PS: 查看 Chubsdad 回答的最后一段,关于如何在 C + + 中不使用 static来表示内部链接,而是使用匿名名称空间。(因为他是对的。;-) )