前置声明 / 何时最好包含头文件?

7

我非常清楚何时可以/不能使用前向声明,但还有一件事不确定。

假设我知道早晚需要包含一个头文件以解引用类A的对象。 我不确定是否更有效率的方式是像这样...

class A;
class B
{
   A* a;
   void DoSomethingWithA();
};

然后在cpp文件中应该有类似这样的内容...
#include "A.hpp"
void B::DoSomethingWithA()
{
   a->FunctionOfA();
}

我是否应该在B的头文件中直接包含A的头文件呢?如果前者更有效率,那么我希望有人能清楚地解释一下为什么,因为我怀疑这与编译过程有关,我总是需要学习更多关于它的知识。

3个回答

12

尽可能使用前向声明(如您的示例所示)。这可以减少编译时间,更重要的是可以最小化不需要知道和不关心实现细节的代码的头文件和库依赖性。通常情况下,除了实际实现之外,没有其他代码应该关心实现细节。

以下是谷歌在此问题上的理由:头文件依赖性


谢谢回答,Google的风格指南看起来会是一本很棒的读物,感谢! - Holly
15
我知道这个帖子已经有些年头了,但是我认为需要指出一下,以防其他人也在寻找理由。谷歌目前的理由似乎已经改变为“尽可能避免使用前向声明,直接#include您需要的头文件即可”。请注意,不要改变原来的意思,并尽量让翻译通俗易懂。 - soulsabr

5
当你使用前向声明时,你明确地表示了"类B不需要知道类A的内部实现,它只需要知道名为A的类的存在"。如果你可以避免包含那个头文件,那就避免它。使用前向声明是很好的做法,因为你可以通过使用它来消除冗余依赖关系。
还要注意的是,当你改变头文件时,会导致包含它的所有文件都被重新编译。
这些问题也将对你有所帮助:
前向声明的缺点是什么?
前向声明的目的是什么?

0

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

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

#ifndef _A_HPP_
#define _A_HPP_

// all your definitions

#endif

那么,如果在B.hpp中使用#include "A.hpp",您可以有一个包含两者的程序,并且它不会崩溃,因为它不会尝试定义任何内容两次。

头文件保护很好,但我们有一个需要很长时间编译的大型项目,我认为“不要试图使您的编译效率高”并不总是好建议。 - Aaron Swan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接