我理解,如果a.h
包含b.h
,并且我没有在我的标题中b.h
声明任何内容,仅包括a.h
,这是一种很好的做法。如果我要在我的标题中声明b.h
中的任何内容,那么我应该同时包含a.h
和b.h
以使我的标题自给自足。
在我的标题中,我确实声明class A
中的a.h
和class B
中的b.h
。但是,class A
取决于class B
,所以我总是一起使用它们。我从不使用class B
独立于class A
。在这种情况下,包含a.h
和b.h
是否仍然有意义?
A.H
#include "b.h"
#include <queue>
class A
{
private:
std::queue<B> mFoo;
}
在我的实际代码中,我认为当我仅包括我的事件系统时,我的意图更清晰,而不是一些对我来说似乎多余的包含。
答案 0 :(得分:0)
您应始终包含直接依赖关系:如果 a 直接取决于 b 和 c ,即使 b 已包含 c , a 应包括两者。你永远不知道依赖树将来会如何变化。
为了确保您不会通过将其包含两次来重新定义某些内容,您可以将header guard放在头文件中:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif /* GRANDFATHER_H */
(维基页面的代码)
您也可以使用
#pragma once
但并非每个IDE都有它。 这样,即使预处理器同步包含多次,它也不会复制代码。
答案 1 :(得分:0)
我的规则:给定一些随机标题foo.h
,以下内容应该编译干净,最好是链接和运行:
#include "foo.h"
int main () {}
假设foo.h
不包含任何语法错误(即,在您打算编译干净的上下文中包含它的源文件),但上述内容仍然无法编译。这几乎总是意味着#include
中有一些缺少foo.h
指令。
这并不能告诉您foo.h
中是否真正需要所有标头。我有一个方便的小脚本来检查上面的内容。如果它通过,它会创建foo.h
的副本并逐步注释掉#include
指令,并查看foo.h
的那些修改版本是否通过了上述测试。任何通过的都表示怀疑是多余的#include
指令。
问题是被认为是多余的#include
指令可能不是多余的。假设foo.h
定义了类Foo
,它具有类型为Bar
和Baz
的数据成员(不是指针,成员)。标头foo.h
正确包含bar.h
和baz.h
,因为这是定义这两个类的位置。假设bar.h
恰好包含baz.h
。作为foo.h
的作者,我不在乎。我仍然应该在foo.h
中包含这两个标头,因为foo.h
对这两个标头都有直接依赖关系。在这种情况下,我的脚本会抱怨可疑的多余标题。这些投诉是暗示,而非强制性。
另一方面,修复foo.h
以便我上面的简单测试程序编译清洁是一项任务。