【问题标题】:Should I include files included in another header?我应该包含另一个标题中包含的文件吗?
【发布时间】:2010-12-11 09:52:07
【问题描述】:
在一个程序中创建多个相互使用的类时,我喜欢只包含我需要的最少数量的头文件以减少混乱。
例如,假设类 C 继承自包含类 A 的类 B。当然,既然类 B 包含类 A 作为成员,则它需要在 b.h 中包含 a.h。但是,假设 C 还需要包含 a.h。像我一样懒惰,我只包含b.h(C 无论如何都需要包含它),并且由于b.h 已经包含a.h,我不需要再包含任何内容,它编译得很好。我的 .cpp 文件也一样:我只包含标题,标题中包含的任何内容都会自动包含在我的 .cpp 文件中,所以我不包含它。
这是我的坏习惯吗?是否会降低我的代码的可读性?
【问题讨论】:
标签:
c++
class
include
code-readability
【解决方案1】:
我坚持这条简单的规则:包含完全声明给定类所需的所有内容,但不多,并且不对包含从其他来源中提取的内容做任何假设,即确保您的文件是自给自足的。
【解决方案2】:
包含在不依赖外部包含排序的情况下解析头文件所需的内容(换句话说:使您的头文件自给自足)。
在你的情况下,如果c.h 声明一个继承自class B 的class C,显然你必须包含B.h。但是,如果class A 从未出现在c.h 中,我相信没有理由包含它。 b.h 提到 A 的事实意味着 b.h 必须通过前向声明 A 或包括 a.h 来解析需要解析的内容。
所以在我看来,你正在做应该做的事情。
还要注意,如果由于某些原因 c.h 开始提及 A,我会添加适当的包含或转发声明,这样我就不会依赖于 b.h 为我做这件事的事实。
【解决方案3】:
最好在每个标题中包含您直接使用的定义。
依赖其他标头之一来包含内容会使您的代码更加脆弱,因为它变得依赖于外部类的实现。
编辑:
一个简短的例子:
B 类使用 A 类,例如使用散列机制 A 的散列表实现 B
您创建了一个 C 类,它需要一个哈希表(即 B)和一个哈希算法(即 A)用于其他目的。您包含 B.h 并省略 A.h,因为 B.h 无论如何都包含它。
Mary,你的一位同事,发现了一篇关于这种新的神话般的散列算法的论文,它降低了冲突的可能性,同时它需要的空间减少了 10%,速度提高了两倍。她(正确地)重写了 B 类以使用实现该算法的 D 类。由于 B 中不再需要 A 类,因此她还从 B.h 中删除了对它的所有引用。
你的代码坏了。
编辑 2:
有一些程序员(我偶尔也会犯这种罪,当赶时间的时候)他们通过在他们的项目中使用“include-all”头文件来处理这个问题。这应该避免,因为它会导致空前比例的命名空间污染。是的,在我看来,MSVC 中的 windows.h 就是其中之一。