首先,您的误解与命名空间无关,它只是关于static. 对于这个答案的其余部分,我将仅引用它,testNum因为它在命名空间中的事实是无关紧要的。
我还假设您有另一个文件,可能名为test.cpp,其中还包含test.h并定义了该setNum函数。
当声明命名空间范围内的变量或函数(即不是类成员或函数本地)时,static这意味着实体的名称在该文件的内部。形式上它具有“内部链接”,这意味着它不能通过名称引用或链接到其他文件(可以通过指针间接引用或将其作为参数传递给另一个函数。)这意味着如果有几个文件定义static int testNum然后每个文件都有自己的内部变量,名称与testNum其他文件不同(实际上一个文件可能有static int testnum,另一个可能有static double testnum,另一个文件static char* testNum,它们都是不同的,并且对于每个文件都是内部的。)如果你在 header 中放置这样的定义,然后包含 header 的每个文件都有自己的testNum.
因此,static在标题中的变量上,您在每个testNum包含test.h. 这意味着如果您在一个文件中设置testNum并在另一个文件中调用一个函数,该函数使用testNum它指的是一个不同的变量,该变量恰好具有相同的名称。
因此,static在标头中声明非常量变量几乎总是错误的。
如果没有static,您将testNum在包含 的每个文件中定义变量test.h,这是不允许的:每个实体必须在您的程序中定义一次且仅一次。解决这个问题的方法是在头文件中声明变量,但不定义它,你可以通过告诉编译器变量是extern:
extern int testNum; // N.B. no "= 1" here
这告诉编译器有一个名为“外部链接”的变量testNum,所以当代码引用testNum它时,它总是意味着相同的变量(不是带有内部 linakge 的某个名称,它是每个文件中的不同实体。)在声明一个extern变量之后,它是您有责任确保在程序中的某处提供了一个确切的定义,因此您只需在一个文件中(即不在包含在多个文件中的头文件中)定义它:
int testNum = 1;