1,声明一个变量,必须加关键字extern
2,没有关键字extern,则就为变量的定义,无论这个变量定义时有没有初始化
3,只要定义变量时初始化了,即使前面加了关键字extern,也是定义,不是声明。(不过只有在函数体外时,才能够在定义且初始化时,加上extern关键字,这是为了const变量设定的)
4,多文件程序中,一个文件含有变量的定义,另外一个文件中含有变量的声明,定义只能有一次,声明不限。
5,非const变量,定义时默认是加了extern的,即在函数体外定义变量时,默认加了extern,说明这是一个全局变量,可以被其他文件访问(访问的前提是在这个文件中做了声明)。
但是const变量,默认是不加extern的,也就是即使在函数体外全局作用域定义一个const变量,也只能够在定义的这个文件访问,不能被其他文件访问。要想被其他文件访问,需要在定义const变量时,显示的加上extern关键词。
extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件(当然也有可能定义就在本文件中)中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"#pragma once" make sure header file was included once in the cpp file when compiling, but extern make sure the varible is defined once when linking different cpp files.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C++编程语言从出现至今已经发展的越发成熟,逐渐成为了开发领域中一个重要的应用语言。今天大家可以从这篇文章中详细了解到有关C++头文件的一些嵌套方法,从而让大家更进一步的对这一语言有一个详细的了解。
在实际编程中,不同的类一般是放在不同的相互独立的C++头文件中的,这样两个类在相互引用时又会有不一样的问题。重复编译是问题出现的根本原因。为了保证头文 件仅被编译一次,在C++中常用的办法是使用条件编译命令。
- Example:
- animal.h
- class animal
- {
- ......
- };
- animal.cpp
- #include "animal.h"
- #include <iostream.h>
- ......
- fish.h
- #include "animal.h"
- class fish
- {
- ......
- };
- fish.cpp
- #include "fish.h"
- #include <iostream.h>
- ......
- main.cpp
- #include "animal.h"
- #include "fish.h"
- void main()
- {
- ......
- }
编译文件,会出现class type redefinition的错误
为什么会出现类重复定义的错误呢?请读者仔细查看EX10.cpp文件,在这个文件中包含了animal.h和fish.h这两个头文件。当编译器编译EX10.cpp文件时,因为在文件中包含了animal.h头文件,编译器展开这个C++头文件,知道animal这个类定义了,接着展开fish.h 头文件,而在fish.h头文件中也包含了animal.h,再次展开animal.h,于是animal这个类就重复定义了。
要解决C++头文件重复包含的问题,可以使用条件预处理指令。修改后的头文件如下:
- animal.h
- #ifndef ANIMAL_H_H
- #define ANIMAL_H_H
- class animal
- {
- ......
- };
- #endif
- fish.h
- #include "animal.h"
- #ifndef FISH_H_H
- #define FISH_H_H
- class fish
- {
- ......
- };
- #endif
我们再看EX10.cpp的编译过程。当编译器展开animal.h头文件时,条件预处理指令判断ANIMAL_H_H没有定义,于是就定 义它,然后继续执行,定义了animal这个类;接着展开fish.h头文件,而在fish.h头文件中也包含了animal.h,再次展开 animal.h,这个时候条件预处理指令发现ANIMAL_H_H已经定义,于是跳转到#endif,执行结束。
但是不要以为使用了这种机制就全部搞定了,比如在以下的代码中:
- //文件A.h中的代码
- #pragma once
- #include "B.h"
- class A
- {
- public:
- B* b;
- };
- //文件B.h中的代码
- #pragma once
- #include "A.h"
- class B
- {
- public:
- A* a;
- };
这里两者都使用了指针成员,因此嵌套本身不会有什么问题,在主函数前面使用#include "A.h"之后,主要编译错误如下:
- error C2501: 'A' : missing storage-class or type specifiers
仍然是类型不能找到的错误。其实这里仍然需要前置声明。分别添加前置声明之后,可以成功编译了。代码形式如下:
- //文件A.h中的代码
- #pragma once
- #include "B.h"
- class B;
- class A
- {
- public:
- B* b;
- };
- //文件B.h中的代码
- #pragma once
- #include "A.h"
- class A;
- class B
- {
- public:
- A* a;
- };
这样至少可以说明,C++头文件包含代替不了前置声明。有的时候只能依靠前置声明来解决问题。我们还要思考一下,有了前置声明的时候头文件包含还是必要的 吗?我们尝试去掉A.h和B.h中的#include行,发现没有出现新的错误。那么究竟什么时候需要前置声明,什么时候需要头文件包含呢?