考虑:
foo.h中:
#include <string>
#include <vector>
class foo
{
std::string a;
std::vector<int> b;
};
bar.h:
#include <string>
#include <vector>
#include "foo.h" // <string> and <vector> included again
class bar
{
std::string c;
std::vector<bool> d;
};
问题:是否需要foo.h中的 #include
?我知道标题保护会阻止多个#include
,但是可以省略foo.h中的#include
吗?
编辑:抱歉,我真正想问的是,是否可以省略bar.h中的#include
,因为它已经包含在foo.h中
答案 0 :(得分:2)
依赖间接包含在任何非平凡的代码库中都存在问题:假设您不包含<string>
中的<vector>
和bar.h
。现在,当foo
更改时,例如,以不同方式存储字符序列并删除<string>
的包含,您的标题bar.h
就会中断。因此,您创建了一个不必要的依赖。
在小型项目中,这些破损并不重要。在大型代码库中,它们很容易变成灾难性的。值得注意的是,班级表征的变化确实有效!
答案 1 :(得分:1)
所有标准头文件都包含防护,因此,从编译器的角度来看,无论是将它们包含在两个文件中还是仅包含在一个文件中都无关紧要。
但从代码清晰度的角度来看确实很重要:阅读文件的人会明确知道,您实际需要string
和vector
才能使此标头正常工作。这也简化了你的生活。想象一下,a.h
使用b.h
,使用c.h
,...,使用z.h
,使用<string>
。你会在#include <string>
中省略a.h
吗?分析这样的代码将是一团糟。
另请注意,如果您省略bar.h
中的包含内容,如果您添加bar.h
但未包含<string>
或<vector>
,则以后可能会遇到问题早些时候。寻找失踪的包含将是一个恐怖。
TL; DR 始终包含所有必需的标头。缺点是编译时间稍长,但有很多更多的好处。
答案 2 :(得分:0)
就像他的评论中提到的juanchopanza一样,您应该在第一步检查foo.h
和bar.h
中是否真的需要插入内容。如果是这样,你应该保留它们。一个原因是,如果您(或除您之外的某个人)更改了bar.h
中的包含内容,您必须始终注意这一点并相应地更改您的代码。由于公共头文件受到保护,您可以通过将它们写入需要它们的每个文件中来避免这种情况。
此外,您的代码更容易理解。如果有人试图进入你的代码,他就不会看到需要什么标题。他要看每一个包括。