2017-08-09 49 views
3

问题是关于包含一个不必要的头,以避免在子文件中多次调用它。 这里的情况,我有几个文件:C++“额外”头文件

srlogger.h 

srinterface.h 

srinterface.cc 
#include <srinterface.h> 
#include "srlogger.h" 

srbinhttp.h 
#include "srinterface.h" 

srbinhttp.cc 
#include <srbinhttp.h> 
#include "srlogger.h" 

srsocket.h 
#include "srinterface.h" 

srsocket.cc 
#include <srsocket.h> 
#include "srlogger.h" 

srhttp.h 
#include "srinterface.h" 

srhttp.cc 
#include <srhttp.h> 
#include "srlogger.h" 

现在,我想要做的就是删除所有显示的.cc文件#include "srlogger.h",而是它包括对srinterface.h文件:

srinterface.h 
#include "srlogger.h" 

因为所有的.cc文件都包含srinterface.h,所以srlogger.h会被覆盖。 现在,为什么这会很糟糕?

请不要说你只应该包含必要的头文件来编译而没有额外的东西,这是不够的解释。

我想知道在实际的例子,为什么这将是坏的。

哦,如果有人从srinterface.h中删除#include "srlogger.h"它会破坏另一个文件,这是一个弱解释。包含后的评论很容易提醒其他人。

最让我感兴趣的是如果它会以不好的方式影响编译,那么对象或可执行文件的大小会因此而改变,这会影响性能吗?

或者你有一个很好的解释,为什么这是不好的。

PS:如果您好奇我为什么要这么做,是因为我在映射文件之间的依赖关系,并且做了这样的事情,我可以在所有依赖关系之间创建图形化可视化,从而更容易了解拼图的各个部分如何组合在一起。将子标题传送到较高层级标题中的公共标题将在所有文件之间创建更有组织的结构。

+1

这并没有解决这个问题,但使用'#包括<...>'系统头和'#包括“...”'为自己的头。 –

+0

@佩特贝克尔 - 我不反对,但你应该解释*为什么*。另外,如果你告诉你的编译器关于你自己的包含目录,那么使用“<>”就可以了。在任何情况下,你的评论并没有解释这两种形式之间的差异,而只是说“做这个”,这实际上并没有那么有用。 –

+1

@JesperJuhl - 我会同意,如果这是一个答案。但事实并非如此,而且也不是为了解决这个问题,而是短暂的,而不是为了开始讨论。 –

回答

3

潜在的负面影响是编译时间之一。如果有人包含不需要它拖拽的头部的头部,则该编译单元的编译时间将会增加,原因不明。

对于几秒钟内编译的玩具项目或小项目(几百个文件),这并没有真正的区别。 但是,当您处理数百万行代码的项目时,它们已经花费了大量一小时的时间进行编译,并且将一个包含到12000个其他文件包含的标题中,因为您无法将其明确添加到实际需要它的120个文件中(但恰巧包含了常见的头文件) - 那么您不会受欢迎,因为您只是将每个人的平均构建时间提高了几分钟。

还有一种风险(在糟糕的代码基础上),您(非理性地)拖拽到其他文件的头可能会重新定义那些打破该源文件的东西,甚至不需要其他头文件。

基于上述原因,认为,标题应该只包括他们真正需要自己,不能向前声明。执行文件应该只有包含头文件他们真的需要(并且包括他们自己的头文件第一个以确保它们是自包含的)。

希望能回答你的问题。

+0

我可以看到你的观点,这很有道理,谢谢。 我也做了一些更多的研究,我猜对象文件和程序会因为它而增加。 我发现显示了编译和链接这个视频很有用,得跳到中间虽然: https://www.youtube.com/watch?v=5UMHbzZGQuE&index=17&list=PLggLP4f-rq02gmlePH-vQJ8PF6hyf08CN – Daniel

1

“的问题是关于包括不必要的报头,以避免调用它在子文件多次。”

包括守卫会解决,包括在同一文件的多个头的这个问题的可行部分。包括警卫将在一定程度上减少不必要的包含。请参见下面的链接:

C++ #include guards

一个包括后卫是通过添加以下到你的头文件提出:

//at the very top of the header 
#ifndef NAMEOFHEADER_H 
#define NAMEOFHEADER_H 

// header info 

//at the very last line of the header 
#endif 

这将让你积累相同的头文件中的另一多次。 h或.cpp文件。

而作为在下面的评论指出,即使每头有包括你仍然可以使用,甚至不需要你的文件的信息由编译器在其预处理指令被定义结束了警卫。这在跨多个文件的包含链中必然会发生。

+1

包括警卫不当标题包含在10000个文件中时可以提供帮助,但是添加到标题中的额外内容仅需要10个。所有10000个源文件现在需要支付编译该额外标题的费用(并且这实际上增加了实时 - 分钟)很快 - 对于大代码库)。 –

+0

好点 - 将添加一个编辑。 – 9Breaker