2011-10-03 56 views
2

我试图尽量减少头项目包含在一个项目中,最大限度地使用正向声明,并需要清楚C++编译的过程如何工作。C++多文件编译过程

它从我们分配对象A的main.cpp开始,因此我们包含A.h. A类使用B类和C类,所以我包括B.h和C.h.现在,如果我想在main.cpp中分配B,编译将会失败。

我很容易在main.cpp中包含B.h,但我想知道它是否真的有必要,因为我已经包括A.h和A.h,我包括B.h.我阅读了一些关于这个主题的讨论,其中有关于源文件的递归和重新编译的内容。那么这究竟是如何工作的?

感谢您的任何建议。 :)

+7

间接包含*是*包含。当你包含一个头文件时,编译器的行为就好像头文件的每一行都是文件的一部分。当您在标题中包含标题时,就好像您将该内部标题的每一行复制/粘贴到外部标题的每一行,并因此复制到每个包含它的文件中。如果编辑在您描述的情况下失败,则其中一个标题已损坏。 (你可以创建一个简短的,完整的,可编辑的破损示例吗?) –

+0

@DavidSchwartz:是的,没有,预处理器设计用于检测标头警卫(和'#pragma once'声明),并避免打开第二个头文件时间。所以是的,理论上你是*再次包括文件,但实际上成本可以优化。 –

+0

@David Schwartz:嗯,现在看来我只是需要重新编译代码,还有一些部分编译的事情正在进行。我开始深入研究这个问题的原因是,我正在解决交叉问题 - 包括两个类和一个朋友告诉我,他使用一个技巧,他包含一个头文件,在这个包含的头文件中,他只是使用前向声明和包括cpp文件中的前一个类标题。所以我很困惑cpp文件在哪里进来。 – Maci

回答

1

作为一个简单的经验法则,您需要在任何时候需要对齐,接口或大小时定义符号。如果头只将一个类型引用为指针,则只需要声明它。

所有引用标题的编译单元都必须经过独立理解的步骤。这就是为什么头中的代码超线性增加编译时间的原因。

如果您有兴趣,您可以准确了解预处理器为编译器准备的内容。 GCC具有以下语法。

g++ -E main.cpp 

虽然我不能引用它,但MSVC具有类似的功能。

我可以很容易地包括了Bh在main.cpp中,但我想知道如果它真的 必要的,因为我已经有包括阿和阿我包括 了Bh

这我想是情况问题。忽略头文件的主要烦恼是,通常发生的是其他人在代码库的不同部分中更改某些内容,并且您必须猜测从源代码控制进行更新时为什么缺少符号。本质上,您可以在根本不清楚的标头之间创建依赖关系。

如果我的异想天开是合法的,你可以将一个include包含到空cpp文件中的任何头文件中,然后它就可以编译。我不明白你为什么不想要这样做,尽管我不打算为所有情况下的辩护做好准备。

+1

“*您需要在任何需要对齐或界面时定义符号*”或大小。 – ildjarn

+0

大小可能是所有它的相关位,ty;) –