前瞻性声明

时间:2011-10-13 16:47:58

标签: c++

当我已经包含相关的头文件时,为什么我需要为类使用前向声明?它解决了我的问题,但让我很困惑!

基本上A类需要了解B类,反之亦然。在我包含前向声明之前,我收到错误“sytax error - identifier”。我的印象包括一个头文件,本质上意味着你在声明另一个你放#include的类。

3 个答案:

答案 0 :(得分:5)

如果你有一个循环包含依赖项,并且你正确使用包含保护(如你所知),那么由于没有无限循环包含,编译器必须在某个时刻停止,并且它不会知道其他标题的内容。当您添加前向声明时,它可以编译您的代码。

例如,A包含B。然后B包含A,但A'包含警卫并且阻止第二次评估。然后它回到B,因为包含守卫阻止了它的包含,因此A.h不知道任何事情。然而,前方声明中没有任何包含防守措施,因此它正常进行。

循环依赖没有任何固有的错误,但我总是建议你再看一下你的设计,看看是否可以将逻辑分解为第三类。前向声明是防止无限循环依赖的C ++机制。

答案 1 :(得分:3)

如果你有一个循环声明依赖,你可能会有这样的东西:

  • A.h已定义class A,并以#include "B.h"

  • 开头
  • B.h已定义class B,并以#include "A.h"

  • 开头

现在,您的头文件将包含防护,因此它们只包含一次。因此,在B.h的上下文中,只包含A.h,因此您将获得有效的内容:

class A { B * bp; };  // from `#include "A.h"`

class B { A * ap; };

现在你被卡住了,因为第一行不正确而没有声明B。您可以通过向A.h添加转发声明来解决此问题:

// A.h
#ifndef H_A
#define H_A

class B;
class A { B * bp; };

#endif

答案 2 :(得分:2)

类之间的反之关系始终需要至少一个前向声明。您可以一次只定义一个类,因此当您定义第一个类时,第二个类到目前为止尚未定义。包含标头是不够的,因为这些标头也应该包括彼此。包含文件与在包含位置粘贴其内容没有什么不同。考虑到这一点,您将如何在单个文件中声明两个相互引用的类?正如您所知,答案是前瞻性声明。