【发布时间】:2011-12-11 02:21:42
【问题描述】:
每当我创建 .h 头文件时,我都会想到一个问题:“如何停止通过分层包含传播声明?” 假设有以下这些文件:
foo.h
#ifndef FOO_H
#define FOO_H
typedef int foo_t;
inline int foo() { return 1; }
class foo_c {};
#endif /* FOO_H */
bar.h
#ifndef BAR_H
#define BAR_H
#include "Foo.h"
typedef foo_t bar_t;
inline int bar() { return foo(); }
class bar_c : public foo_c {};
#endif /* BAR_H */
zoo.h
#ifndef ZOO_H
#define ZOO_H
#include "Bar.h"
typedef bar_t zoo_t;
inline int zoo() { return bar(); }
class zoo_c : public bar_c {};
#endif /* ZOO_H */
在文件 zoo.h 中,我们可以访问声明的元素 foo_c、foo_t、foo(),并且对 foo.h 的每次更改都会重新编译 zoo.h
我知道我们可以将实现移动到 .cpp 文件中,但是在 .h 文件中的类定义中编写的代码呢?如果需要,我们如何强制程序员在 zoo.h 中显式包含 foo.h?
作为 Qt 中的示例,当我包含和使用 <QQueue> 时,我无法访问 QList,其中 QQueue 由 QList 继承,我必须明确包含 <QList>。 (另外,我不知道它是如何完成的,以及它对编译时间的影响)
【问题讨论】:
-
您对 protect 的使用表明有些东西需要保护。防止什么?有什么问题?
-
@RobKennedy:阅读有关编译时间的更新问题。
-
我不确定这是否有帮助,但我有一个减少标题依赖的技巧。如果你只使用指针或引用的类型,你可以直接声明它而不是包含它的头。
-
如果 QQueue 继承自 QList,那么我向您保证,每次使用 QQueue 时,您还编译了 QList 的所有代码,无论您是否明确包含 qlist.h。如果您认为我错了,请发布演示您要解决的问题的代码。
-
您通常通过分离声明和定义来保护自己免受标题更改的影响。 (假设函数声明的更改频率远低于实现。) - 如果您在标头中实现所有内容,那么您基本上会得到一个包含所有内容的编译单元。
标签: c++ c header-files