前向声明/何时最好包含标题?

Posted

技术标签:

【中文标题】前向声明/何时最好包含标题?【英文标题】:Forward declaration / when best to include headers? 【发布时间】:2012-05-06 09:35:35 【问题描述】:

我很清楚何时可以/不能使用前向声明,但我仍然不确定一件事。

假设我知道我迟早必须包含一个标头来取消引用 A 类的对象。 我不清楚这样做是否更有效..

class A;
class B

   A* a;
   void DoSomethingWithA();
;

然后在 cpp 中有类似的东西..

#include "A.hpp"
void B::DoSomethingWithA()

   a->FunctionOfA();

或者我是否也可以首先在 B 的头文件中包含 A 的头文件? 如果前者更有效,那么如果有人清楚地解释为什么我会很感激,因为我怀疑它与编译过程有关,而我总是可以通过了解更多来做。

【问题讨论】:

【参考方案1】:

尽可能使用前向声明(如您的示例)。这减少了编译时间,但更重要的是最大限度地减少了不需要知道也不关心实现细节的代码的头文件和库依赖关系。一般来说,除了实际实现之外,没有其他代码应该关心实现细节。

这是 Google 对此的理由:Header File Dependencies

【讨论】:

为回答干杯,Google 的风格指南看起来会很不错,谢谢! 我知道这个帖子很旧,但我想我应该指出,以防万一其他人在寻找理由,Google 的理由似乎已更改为“尽可能避免使用前向声明。只是#include 你需要的标题。”【参考方案2】:

当你使用前向声明时,你明确地说“B类不需要知道A类的内部实现,它只需要知道名为A的类存在”如果您可以避免包含该标头,请避免使用它。 - 使用前向声明是一种很好的做法,因为您可以通过使用它来消除多余的依赖关系。

另请注意,当您更改头文件时,会导致重新编译包含它的所有文件。

这些问题也会对您有所帮助:What are the drawbacks of forward declaration?What is the purpose of forward declaration?

【讨论】:

【参考方案3】:

不要试图让你的编译高效。有龙。只需在B.hpp 中包含A.hpp

C 和 C++ 头文件的标准做法是将所有头文件包装在 #ifndef 中,以确保它只编译一次:

#ifndef _A_HPP_
#define _A_HPP_

// all your definitions

#endif

这样,如果您在B.hpp#include "A.hpp",您可以拥有一个包含两者的程序,并且它不会中断,因为它不会尝试定义任何东西两次。

【讨论】:

标头守卫很棒,但我们有一个大型项目需要一段时间来编译,我不认为“不要试图让你的编译高效”总是很好的建议。

以上是关于前向声明/何时最好包含标题?的主要内容,如果未能解决你的问题,请参考以下文章

模板方法何时可以使用稍后定义的函数,而无需前向声明?

C ++包含与前向声明策略[关闭]

类前向声明​​失败,没有递归包含

使用一个大的包含文件的优点/缺点

类成员的前向类声明

我需要相互包含两个头文件,而不是使用前向声明导致“不完整类型”错误