头文件和源代码文件包含内容的区别
- 头文件:包含结构声明和使用这些结构的函数的原型
- 源代码文件:包含与结构有关的函数的代码
- 源代码文件:包含调用与结构有关的函数的代码
头文件常包含的内容
- 函数原型
- 使用#define或者const定义的符号常量
- 结构声明
- 类声明
- 模板声明
- 内联函数
一般头文件只声明不定义的原因
假如有一个头文件中有变量的定义,当这个头文件被多个.c文件包含的时候,在链接的时候就会在不同的编译单元导出符号表中查 找出重复的定义,就会报错。
类可以定义在头文件中的原因
类的定义默认是static,内部链接,在其他的编译单元不可见,即使被重复包含
头文件管理
如果文件名包含在尖括号中,则C++编译器首先查找当前的工作目录或者源代码目录(或其他,这取决于编译器。如果没有在那里找到头文件,则将在标准位置查找。另外,不要使用#include来包含源代码文件,这样将导致多重声明,也不要在源代码文件中使用#include来包含其他源代码文件。 在同一个文件中只能将同一个头文件包含一次,记住规则很容易,但是很可能在不知情的情况下将头文件多次包含。例如,可能使用包含了另外一个头文件的头文件。但是有一种很标准的C/C++技术可以避免多次包含同一个头文件。另外,不要使用#include来包含源代码文件,这样将导致多重声明,也不要将头文件加入到项目列表中。
预编译
预处理过程实质上是处理“#”,将#include包含的头文件直接拷贝到源文件当中;将#define定义的宏进行替换,同时将代码中没用的注释部分删除等
具体做的事儿如下:
(1)将所有的#define删除,并且展开所有的宏定义。说白了就是字符替换
(2)处理所有的条件编译指令,#ifdef #ifndef #endif等,就是带#的那些
(3)处理#include,将#include指向的文件插入到该行处
(4)删除所有注释
(5)添加行号和文件标示,这样的在调试和编译出错的时候才知道是是哪个文件的哪一行
(6)保留#pragma编译器指令,因为编译器需要使用它们。
重定义可能的解决办法
-
在头文件头加上
#ifndine _xx_H_ #define _xx_H_ ...... ...... #endif
注意:这种方法并不能防止编译器将头文件包含两次,只是让他忽略除了第一次包含之外的所有内容。否则,可能在一个文件中定义同一个结构两次,这将导致编译错误。
-
如果在头文件里面定义了变量例如
int a;
可能会导致重定义的出现,如果出现了变量的重定义,则把在头文件定义的变量放在源文件中定义(不能放在头文件中定义),然后在头文件中声明该变量。 这样,这个变量带来的重定义错误就会消除。同时如果其他源文件需要使用该变量,仅需要在源文件中添加头文件即可使用。
Comments | NOTHING