为什么要声明您作为头文件包含的类?
#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:
...
}
答案 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)
如果你的头文件是正确的,我认为没有必要声明它们,因为它们应该已经在头文件中声明了