龙空技术网

头文件相互包含问题

记录知识点滴 680

前言:

当前兄弟们对“头文件能包含头文件吗”大约比较讲究,同学们都需要学习一些“头文件能包含头文件吗”的相关文章。那么小编同时在网络上汇集了一些有关“头文件能包含头文件吗””的相关资讯,希望姐妹们能喜欢,姐妹们快快来了解一下吧!

原文链接:

何谓?头文件相互包含

即头文件a包含了头文件b、头文件b又包含了头文件a

分类仅头文件相互包含,内容无相互引用

a.h 内容

#include "b.h"

#define a 11

b.h 内容

#include "a.h"

#define b 22

source.c内容

#include "a.h"

#include "b.h"

void main(){

printf ("%d %d \n", a,b);

}

头文件相互包含,且内容相互引用

-------------------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;

}

解决方案无内容引用包含问题

头文件添加

#ifndef _a_h

#define _a_h

....

#endif

内容相互引用包含问题

相互引用代码编译完之后会报错,大致意思是 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 的定义的错误了

修改方法:调整代码甚至.h文件的顺序

****************************修改后的两个头文件

-------------------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

注意结构体和类,可以在定义前进行预声明

struct _A *a;

typedef struct _A{

...

}A;

struct _A *a;//结构体的定义出现之前,只能用该形式的预声明,不可以用下面的形式

A *a;//结构体的定义出现之后,可以用该形式的预声明

其次,不是所有的.h文件都要放在文件开头,要注意调整#include *.h文件的顺序和位置

标签: #头文件能包含头文件吗 #头文件一般包含哪些内容 #头文件包括什么