为什么声明您作为头文件包含的类?

时间:2012-09-06 15:21:01

标签: c++

为什么要声明您作为头文件包含的类?

#include "TreeCallObj.h"
#include "TreeDevObj.h"
#include "TreeDevCallObj.h"

class TreeCallObj; //what is the purpose of this line ?
class TreeDevObj;  //what is the purpose of this line ?
class TreeDevCallObj;  //what is the purpose of this line ?


class Apple
{
public:
...
private:
...
}

8 个答案:

答案 0 :(得分:6)

考虑一下:

//a.h
#ifndef A_H
#define A_H

#include "b.h"
class A
{
   B* b;
};
#endif

//b.h
#ifndef B_H
#define B_H

#include "a.h"
class B
{
   A* a;
};
#endif

现在您尝试将其中一个文件包含在另一个文件中,例如#include "a.h"

编译器将其解析为:

#ifndef A_H
#define A_H

罚款 - A_H未定义

#include "b.h"

尝试粘贴内容:

#ifndef B_H
#define B_H

好的,因为B_H未定义

#include "a.h"

这不会定义A,因为A_H已定义。接下来,我们有

class B
{
   A* a;
};

会导致错误,因为在使用之前未定义或声明A

前方声明解决了这个问题。

当然,最好的解决办法是不要包括(除非你绝对必须)。

答案 1 :(得分:5)

  

这条线的目的是什么?

理想情况下没有。这是多余的。

然而,正如@Luchian Grigore指出的那样,可能存在如此设计糟糕的代码,由于不正确使用包含警戒和交叉包含,前向声明可能是必要的。

答案 2 :(得分:3)

如果在文件中有类的定义,那么在正常情况下,forward declaration是不必要的。

答案 3 :(得分:1)

完全没有理由。您需要根据具体情况做一个或另一个,但不能两者兼而有之。

答案 4 :(得分:1)

目前看来,没有必要。

然而,这可能在历史上有所发展:在某些时候,不完整的类型可能已经足够了:

class Foo;

struct Gizmo
{
    void f(Foo);
};

然后,在稍后,作者决定她需要完整的类型:

#include "Foo.hpp"

class Foo;

struct Gizmo
{
    void f(Foo);
    Foo x;
};

原始代码可能只是修改了现在必需的标题包含...

答案 5 :(得分:1)

我猜这里有一些历史。在编码器中,编码器试图不包含头文件,而是使用前向声明。然后随着代码的扩展,他们发现他们毕竟需要头文件,但是没有费心去删除前向声明。

正如其他人所说,在集体声明后没有任何目的可以提出前瞻声明。

答案 6 :(得分:1)

我注意到你的标题没有防止多重包含。此外,一些包含的其他标题(标题通常有这样的警卫)也可能包含该标题。结果它没有编译。所以有人添加了前向声明来修复错误的bug。

答案 7 :(得分:0)

如果你的头文件是正确的,我认为没有必要声明它们,因为它们应该已经在头文件中声明了