遇君阁

前不见古人,后不见来者
念天地之悠悠,独怆然而涕下

  VC知识库BLOG :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 登录 ::
  26 随笔 :: 8 文章 :: 53 评论 :: 0 Trackbacks
<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

留言簿(0)

随笔分类

随笔档案

文章分类

文章档案

相册

相关链接

搜索

最新评论

阅读排行榜

评论排行榜

编译环境VS 2005

首先我们先建立一个项目,项目文件有:

A.h

B.h

C.h

A.cpp

B.cpp

C.cpp

 

文件内容如下:

A.h

#ifndef EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6

#define EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6

#include "B.h"

 

class A

{

public:

     B b;  //其实不应该用一个对象,应该用指针,这里只是为了说明问题

};

 

#endif

 

B.h

#ifndef EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6B

#define EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6B

#include "C.h"

 

class B

{

public:

};

 

#endif

 

C.h

#ifndef EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6C

#define EVENTHANDLER_CEVENTHANDLER_H_HEADER_INCLUDED_BA392BB6C

#include "A.h"

 

class C

{

public:

};

 

#endif

 

A.cpp

#include "A.h"

 

B.cpp

#include "B.h"

 

C.cpp

#include "C.h"

 

我们先做一个试验,分别注释掉A.cpp,B.cpp,C.cpp中的包含文件,每次只留下一个,比如第一次(A情况)注释掉:B.cppC.cpp中的包含文件语句,第二次(B情况)注释掉A.cpp,C.cpp中的包含文件语句,第三次(C情况)注释掉:A.cpp,C.cpp中的包含文件语句,便以结果如下表:

测试用例

编译结果

A

编译通过

B

编译出错syntax error : missing ';' before identifier 'b'

C

编译通过

 

为什么在B情况下会出现b标识符没有找到呢?我们来分别分析一下这几种情况:

A情况中只有 A.cpp文件中包含A.h,那么编译器开始首先编译A.cpp文件,它首先看到#include A.h语句,这时它并不是立刻展开A.h,而是会到A.h里再找是否有包含别的.h文件,如果有编译器则再到那个.h文件里再找是否有包含其他的.h文件,直到最低层,所以情况变成了在A.h中又找到#include B.h,然后又在C.h里找到#include A.h但此时A.h已经包含过一次了,所以跳出。最终在A.cpp文件里的内容可能是这样:

class C

{

public:

};

 

class B

{

public:

};

 

class A

{

public:

     B b;

};

 

B情况的分析过程与A类似,在B.cpp文件里的内容可能是这样:

class A

{

public:

     B b;

};

 

class C

{

public:

};

 

class B

{

public:

};

 

C情况的分析过程一样,在C.cpp文件里的内容可能是这样:

class B

{

public:

};

 

 

class A

{

public:

     B b;

};

 

class C

{

public:

};

 

经过上面的代码可以看出,显然B情况是错误的,而且确实B在出现以前并没有声明。

其实头文件包含过程很像一个栈的调用过程,编译器会去找文件中包含的那个头文件里是否包含其他的头文件,直到找到最底层头文件或没有包含头文件为止,然后再一层一层返回展开头文件里面的内容。

 

这篇文章的目的是为了说清楚头文件出现循环包含时,代码可能的呈现,因为只要你知道代码的呈现就很容易解决头文件循环包含的错误,就上上面变量没有找到的错误。文章仓促写成肯定会有错误,望大家多指正交流。有什么问题可以在blog上面联系我或Email:eyesonyhm@163.com

 

 

(原创文章,如需转载请注明出处)

posted on 2007-06-01 12:26 游游的家 阅读(2539) 评论(3)  编辑 收藏

评论

# re: 都是头文件的循环包含惹的祸 2007-06-01 14:20 hpho
本来就应该把所有有可能用到的类前向声明. 即做一个被任何头文件所引用的头文件, 如:
// h1.h
#ifndef __H1__
#define __H1__
class A;
clsss B;
class C;
#endif

所有项目的文件的头文件都加上这个文件又或者只在主编译main.cpp的最顶部引用.

# re: 都是头文件的循环包含惹的祸 2007-06-01 15:14 eyesonyhm
to[hpho]:
你说的对的,在头文件里应该减少头文件之间的编译依赖性,在这里我只想说头文件循环包含可能出现的问题。谢谢你!

# re: 都是头文件的循环包含惹的祸 2007-11-26 18:13 yjs
只是依靠类的前向声明,是解决不了这个问题的,还是应该想办法避免这种循环为好,类的前向声明目的是为了解决重复定义的问题

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]