//防止头文件重复包含和交叉包含导致的问题
//只需要增加如下代码段在头文件开头
//第一次包含了该头文件后,就已经#define 了一次_COM_UTIL_H_,第二次包含时会遇到“#ifndef _COM_UTIL_H_”的判断,
//既然已经定义,条件不成立,后面的不再执行,头文件就不会再加进去
//这里的头文件为com_util.h
#ifndef _COM_UTIL_H_
#define _COM_UTIL_H_
//这里是com_util.h的内容
#endif
****************************现在有两个头文件
-------------------head1.h文件内容
#ifndef __HEAD_1_H__
#define __HEAD_1_H__
#include "head2.h"
#define VAR_MACRO 1 ///这里define a macro, which used in head2.h
bool func(ClassA* CA); ///ClassA is defined in head2.h
#endif
-------------------head2.h文件内容
#ifndef __HEAD_2_H__
#define __HEAD_2_H__
#include "head1.h"
class ClassA{
int mVar;
void setMem(){ mVar = VAR_MACRO }; //macro VAR_MACRO is defined in head1.h
... //other members and functions
};
#endif
现在另有两个源文件
---------------------source1.cpp----------------------
#include "head1.h"
int main(){
//... some source code
return 0;
}
---------------------source2.cpp---------------------
#include "head2.h"
int main(){
//... some source code
return 0;
}
上述代码编译完之后会报错,大致意思是 ClassA 和 VAR_MACRO 没有定义.
对于 source1.cpp
,它包含了头文件 head1.h
,那么在编译之前,在 source1.cpp
中展开 head1.h
,而 head1.h
又包含了 head2.h
, 那么也展开它,这时 source1.cpp
就变成类似下面这样:
------------------source1.cpp 的展开
//注意这句#include "head1.h",由于#ifndef __HEAD_1_H__的存在,而不会再包含
class ClassA{
int mVar;
void setMem(){ mVar = VAR_MACRO }; //macro VAR_MACRO is defined in head1.h
... //other members and functions
};
#define VAR_MACRO 1 //define a macro, which used in head2.h
bool func(ClassA* CA); //ClassA is defined in head2.h
int main(){
//... some source code
return 0;
}
===========================================================================================
source1.cpp 会出现 VAR_MACRO 的定义的错误,因为VAR_MACRO 的使用在定义之前.
同理展开source2.cpp:
------------------- source2.cpp 的展开:
#define VAR_MACRO 1 //define a macro, which used in head2.h
bool func(ClassA* CA); //ClassA is defined in head2.h
class ClassA{
int mVar;
void setMem(){ mVar = VAR_MACRO }; //macro VAR_MACRO is defined in head1.h
... //other members and functions
};
int main(){
//... some source code
return 0;
}
===========================================================================================
func 函数声明之前并没有发现 ClassA 类型定义,该定义在函数声明的后面,这时候如果能在head1.h 的
函数声明之前加上 ClassA CA; 的前置声明,就不会在编译的时候报找不到 ClassA 的定义的错误了。
****************************修改后的两个头文件
-------------------head1.h修改:将VAR_MACRO宏定义放在#include "head2.h" 前
#ifndef __HEAD_1_H__
#define __HEAD_1_H__
#define VAR_MACRO 1 ///这里define a macro, which used in head2.h
#include "head2.h"
//ClassA CA; ///也可以直接在这里作ClassA CA前置声明,则head2.h不用再做下面的修改,可保持原状
bool func(ClassA* CA); ///ClassA is defined in head2.h
#endif
-------------------head2.h修改:在#include "head1.h"前,添加预声明 ClassA CA;
#ifndef __HEAD_2_H__
#define __HEAD_2_H__
ClassA CA; ///如果head1.h添加了预定义,这条语句可以删除,建议这里删除
#include "head1.h"
class ClassA{
int mVar;
void setMem(){ mVar = VAR_MACRO }; //macro VAR_MACRO is defined in head1.h
... //other members and functions
};
#endif
注意,不是所有的.h文件都要放在文件开头,要注意调整#include *.h文件的顺序和位置,
例如在com_def.h文件中,把大部分.h文件放在该文件的最后:
https://blog.csdn.net/hazir/article/details/38600419文章给出了非常好的解释.感谢作者的贡献.
https://blog.csdn.net/zyz394515661/article/details/83218462文章亦可作为参考.