2013-08-31 247 views
3

我正在开发一个项目,每个头文件都有一个预处理程序include guard。 我包括由这样的:C++头文件包含

(文件 - >包括)

的main.cpp - > header.h; Character.h

header.h - >载体的iostream,...,DataFiles.h

Character.h - > DataFiles.h,header.h,CharFrame.h

CharFrame.h - > DataFiles.h,header.h

一切工作正常。但是,如果我只是擦除main.cpp的#include“Character.h”以将其移到header.h中,那么在编译时会出现很多错误。所以,现在,它是:

的main.cpp - > header.h

header.h - > ...,DataFiles.h,Character.h。

有什么区别?

这里是我的compilator输出:

Inspiron-1545:~/Desktop/LF2_linux$ g++ -Wall main.cpp DataFiles.cpp header.cpp Character.cpp CharFrame.cpp -lSDL -lSDL_image -lSDL_ttf -o test 
In file included from header.h:13:0, 
      from CharFrame.h:12, 
      from CharFrame.cpp:1: 
Character.h:55:15: error: ‘CharFrame’ was not declared in this scope 
Character.h:55:25: error: template argument 1 is invalid 
Character.h:55:25: error: template argument 2 is invalid 

如果包括被放回的main.cpp,然后它编译没有任何错误。

如果您觉得我的代码是必需的,我会编辑这篇文章并粘贴所有内容。

这里有感兴趣的线路:

header.h:13 -> 
#include "Character.h" 
CharFrame.h:12 -> 
#include "header.h" 
CharFrame.cpp:1 -> 
#include "CharFrame.h" 
Character.h:55 -> 
std::vector <CharFrame*> *frame; 
+0

听起来像'header.h'使用'CharFrame',但它被包含(使用)在'CharFrame'声明之前的'CharFrame.h'中。所以编译器在声明之前就嘲讽了'CharFrame'。 –

+0

如果你正在做你说的话,应该没有区别。但由于某些原因,编译器无法识别“CharFrame”类型。你可以发布[SSCE](http://sscce.org/)来重现此问题吗? – Mahesh

+0

DataFiles.h是否包含其他的? –

回答

5

你改变Character.h和header.h之间创建了一个包含循环。

据推测,Character.h依赖于headers.h中的一些声明。现在,你的变化,会发生以下情况:

  1. headers.h包括,定义了包括后卫和预处理开始检查其内容。

  2. headers.h包含Character.h,然后它进行自己的声明。

    1. Character.h定义了它的包含guard,预处理器读取它的内容。

    2. Character.h包含header.h以获取所需的定义。

      1. headers.h然而看到它的包含守卫,并被解析为空。尚未定义。
    3. 读取Character.h定义。

  3. headers.h定义被读取。

正如你所看到的,Character.h中的定义是在它们依赖的header.h中的定义之前被读取的。

修复循环包含的最佳方法是尽可能用前向声明替换#include。在某些罕见情况下,可能需要将声明与包含实际混合使用,但是您应该不惜一切代价避免这种情况。

+0

感谢这完成了khajvah链接中的解释,其中的例子让#include s不应该像刚刚所说的那样:) –