首先要说明的是:在C++中,.h 文件中的“变量定义”,如 int n,确切的说应该叫做“变量声明”,其实它并没有被定义。只有在 .cpp 文件中的才叫做“变量定义”。
extern的使用:
.h 文件中extern int n 就是要告诉包含该头文件的 .cpp 文件,这个变量n是在外面定义的。在所有包含这个 .h 文件的 .cpp 文件中,这个变量n只能出现一次定义int n。这个变量在任何一个文件中被改变,所有的文件中的函数都会看到它的变化。
例如,有三个文件,分别如下
////////////////////////////////////
h1.h
extern int n;
////////////////////////////////////
h2.cpp
#include "stdio.h"
#include "h1.h"
int n;
void f2()
{
n=5;
printf("h1 %d/n",n);
}
////////////////////////////////////
cpp.cpp
#include "stdio.h"
#include "h1.h"
extern void f2();
void main()
{
n = 3;
printf("/ncpp %d/n",n);
f2();
printf("/ncpp %d/n",n);
}
////////////////////////////////////
在cpp.cpp 文件中使用到n时,它发现这个变量是在外部定义的,于是搜索工程中所有的文件,查找变量n的定义,在h2.cpp中找到定义,将变量赋值为3,第一次输出结果为3,然后调用f2(),在h2.cpp中的这个函数将n赋值为5,结果输出为5,返回到cpp.cpp时,n的结果仍然为5,所以输出结果如下:
cpp 3
h1 5
cpp 5
Press any key to continue
////////////////////////////////////
注意:在这个过程中,变量n定义且只定义了一次,如果任何 .cpp 文件中都没有定义n,则系统会报如下错误
Compiling...
h2.cpp
Linking...
cpp.obj : error LNK2001: unresolved external symbol "int n" (?n@@3HA)
h2.obj : error LNK2001: unresolved external symbol "int n" (?n@@3HA)
Debug/cpp.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
cpp.exe - 3 error(s), 0 warning(s)
这就是因为两处对n的使用,都没有找到n的定义。
////////////////////////////////////
static的使用:
.h 文件中 static int n 就是要告诉包含该头文件的 .cpp 文件,这个变量n你自己要重新定义一次,并且只能在你自己内部使用。有多少 .cpp 文件包含这个 .h 文件,就会有多少个变量n的副本分别在这些 .cpp 文件中被定义,并且这个每个副本是独立的,在一个文件中改变n不会影响另一个文件中的n。
例如,有三个文件,分别如下
////////////////////////////////////
h1.h
static int n;
////////////////////////////////////
h2.cpp
#include "stdio.h"
#include "h1.h"
void f2()
{
n=5;
printf("h1 %d/n",n);
}
////////////////////////////////////
cpp.cpp
#include "stdio.h"
#include "h1.h"
extern void f2();
void main()
{
n = 3;
printf("/ncpp %d/n",n);
f2();
printf("/ncpp %d/n",n);
}
////////////////////////////////////
每一个包含 h1.h 的 .cpp 文件都会自动的在自己的文件中隐含的定义一个n的副本,两个 .cpp 中的n互不影响,所以输出结果如下:
cpp 3
h1 5
cpp 3
Press any key to continue
////////////////////////////////////
注意:每个包含 h1.h 的 .cpp 文件都会自动的在自己的文件中隐含的定义一个n的副本因此不能再显示的定义全局的变量n了,否则会报重复定义的错误的。
static 修饰函数或变量,会使得空间作用域变小,而时间生命期变长。
static 修饰函数时 ,这个函数只能在当前文件中使用。
////////////////////////////////////
全局变量:
如果在上面的例子中没有在 .h 文件的变量n声明前加static,那么变量n就声明全局变量,它在两个包含它的 .cpp 文件中都会隐含的重新定义n的副本,而且这两个副本都是全局多文件可见的,于是就产生了重复定义的错误,虽然你一次显示的定义都没做,只在 .h 文件中做了一次全局变量声明。
另外,"include ***.h"相当于将.h中的内容在包含其的文件中重新写了一遍。
总结:不要在头文件中定义全局变量!反正多个.cpp文件包含时的重复定义!