C ++前向声明和标头包含

时间:2015-01-18 23:43:51

标签: c++

我有一个关于何时使用前向声明与包含标头的问题。我知道有很多类似的问题,但只有一件事情有点令人困惑。

我在我看到的源代码中看到了以下方式:

classA.h

#ifndef H_CLASSA
#define H_CLASSA

class classB;

class classA {
public:
    classA(B* b);
};

然后在 classA.cpp

#include "classA.h"
#include "classB.h" // dependency
classA::classA(B* b) { b->someMethod(); }

在这种情况下,我只是把#include" class.b"从一开始就在classA-header中,因为A依赖于B类并使用它。但是我不明白你为什么要先在头文件中声明classB然后在源文件中包含classB.h?

提前致谢!

1 个答案:

答案 0 :(得分:1)

为了防止循环包括:

假设我们有以下包含路径:(每个[]是一个头文件,每个 - >包含)

[A] - > [B] - > [C]

到目前为止一切顺利。 但是如果[A]有一些类或函数从[C]中取一些对象作为参数会发生什么? 所以我们可以在[A]中包含(就像你说的那样)[C]。 不,我们可以遇到以下问题: 1)此循环包括可能导致编译器的一些错误: 首先,C包括B,B包括A,但A包括C!并且循环继续递归。 2)让我们说[A]有一个A类,[B]有一个继承自A的类B,[C]有一个继承自B的C类。 假设编译器可以处理错误1,但是,你可能会得到“Base class not defined”错误,因为[A]被编译,在编译A之前,所有包含的标题([B]和[C])都是编译。 C被编译为A和B的子类,但此时甚至不存在嘿,B和A!

这是前瞻性声明的便利之处。它允许我说“有2个类,B和C,仍然没有编译”,并且在cpp文件中实际使用了头文件

但是这个解决方案仍然存在一些问题。您只能使用前向声明为指针和引用的类。但是,即便如此,也建议将对象作为引用或const引用传递。所以你可以在[A]中使用C和B作为参考。