最好不要在头文件定义全局变量,很可能会出现重定义,即使使用了ifndef。
因为ifndef只是让预编译时头文件展开不包含重复的头文件,最后每个cpp文件的代码是包含了所有的include了的头文件的代码;
比如A.cpp包含了a.h,和b.h,a.h又包含了b.h,B.cpp包含了a.h;如果在b.h定义了一个全局变量,在编译时不会出错,在链接时就会出错了。
这是因为ifndef只是告诉A.cpp:a.h包含了b.h,不用再包含一次了;而B.cpp包含了ab两个头文件也可以编译成功,这样就cpp文件就生成了两个包含b.h的代码的obj文件,在链接时发现两个obj文件定义了同一个变量,就出现重定义错误了。
因此头文件里最好只声明全局变量(可以成功是因为可能只被include一次),声明必须使用extern T x;
,如果不用extern也视为定义只是没有初始化。
但需要在何处定义呢,只需要注意不能在其他头文件定义,这和前面说的是同样的道理。可以在任意的一个cpp文件里再定义一次,注意是定义不是赋值,定义要写上类型。但最好把**.h声明和.cpp定义关联起来**,因此不要随便找个cpp就定义。
其次,直接在cpp定义而不在.h文件声明是可行的,不过这会导致.h文件内依赖该变量的代码编译失败。但这些代码可以放到cpp内而解决这个错误,见仁见智了。
总结:
- 不要在头文件定义全局变量,声明必须使用extern
- 定义可以在任意一个cpp文件进行,但这个cpp文件最好和原来的.h文件关联起来,比较直观。