【问题标题】:C++ headers inclusionsC++ 头文件包含
【发布时间】:2013-08-31 14:19:28
【问题描述】:

我正在做一个项目,每个头文件都有一个预处理器包含保护。 我的包含是这样的:

(文件 -> 包含)

main.cpp -> header.h;字符.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.

有什么区别?

这是我的编译器输出:

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

如果将 include 放回 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;

【问题讨论】:

  • 听起来像header.h 使用CharFrame,但它在CharFrame 声明之前包含(使用)在CharFrame.h 中。所以编译器在声明之前偶然发现了CharFrame
  • 如果你按照你说的做,应该没有区别。但是由于某种原因,编译器无法识别类型CharFrame。你可以发SSCE 来重现这个问题吗?
  • DataFiles.h 是否包括任何其他文件?
  • 我认为你不能有 2 个相互直接包含的标题(header.h、charframe.h)。如果您有circular dependency,则可以使用多种解决方案之一。
  • @AlexandreToqué this 建议将前向声明作为解决方案。在 header.h 中前向声明 charframe 类并在 header.cpp 中实现它

标签: c++ header include


【解决方案1】:

您的更改在 Character.h 和 header.h 之间创建了一个包含循环。

据推测,Character.h 依赖于 headers.h 中的一些声明。现在,随着您的更改,会发生以下情况:

  1. headers.h 被包含,定义其包含保护,预处理器开始检查其内容。

  2. headers.h 包含 Character.h,在它自己声明之前。

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

    2. Character.h 包含 header.h 以获得它需要的定义。

      1. headers.h,但是看到它的包含保护,并被解析为空。尚未做出定义。
    3. Character.h 定义被读取。

  3. headers.h 定义被读取。

如您所见,Character.h 中的定义在 header.h 中的定义之前读取,它们所依赖的。

修复循环包含的最佳方法是尽可能将#includes 替换为前向声明。在极少数情况下,实际上可能需要将声明与包含混合在一起,但您应该不惜一切代价避免这种事情。

【讨论】:

  • 感谢这完成了 khajvah 链接中的解释,其中示例将 #include 保留在您刚才所说的不应该的位置:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多