用户创建的标题导致C2061:语法错误:标识符'classname'

时间:2011-06-29 02:27:11

标签: c++ syntax-error

所以,我有点期待这最终成为一个简单的答案,但我现在已经被黑客攻击了一段时间,似乎无法解决这个问题。所以我有一个特定的类Intersection,当包含在任何其他标题中时,我会:

error C2061: syntax error : identifier 'Intersection'

这是我的交叉头:

#ifndef INTERSECTION_H
#define INTERSECTION_H

#include "Coord.h"
#include "Road.h"
#include "TrafficLight.h"

class Intersection {
private:
    int id;
    Coord * midPoint;
    Road * northRoad;
    Road * eastRoad;
    Road * westRoad;
    Road * southRoad;
    TrafficLight * trafficLight;
public:
    Intersection(int, Coord *, Road *, Road *, Road *, Road *);
    ~Intersection();
    void transitionTrafficLight();
    int getId();
    Road * getNorthRoad();
    Road * getEastRoad();
    Road * getWestRoad();
    Road * getSouthRoad();
    TrafficLight * getTrafficLight();
};

#endif

现在,如果我尝试在其他地方使用此类,我会收到错误。例如:

#ifndef ROAD_H
#define ROAD_H

#include "Coord.h"
#include "Intersection.h"
#include <string>

class Road {

public:
    enum LaneCount { TWO_LANE = 2, FOUR_LANE = 4 };
    Road(std::string, Coord *, Coord *, LaneCount, Intersection *, Intersection *, int);
//shortened

特别是在Road构造函数(以及引用Intersection的任何其他类)。我不认为这是一个语法问题,因为Coord是另一个类,以相同的方式定义,并且编译器(VS 2008)不会抱怨它。特别是Intersection,这给了我这个麻烦。 :/

我正在标记它的作业 - 这就是它的用途,即使这只是一个我无法摆脱的错误而不是问题的一部分。

思想?

1 个答案:

答案 0 :(得分:26)

看起来错误是你有两个循环包含的头文件 - intersection.h和road.h.这样做往往会导致C ++出现奇怪的意外,因为包括警卫的工作方式。例如,假设我有两个头文件,如下所示:

// File: A.h
#ifndef A_Included
#define A_Included

#include "B.h"

class A {};

void MyFunction(B argument);
#endif

// File: B.h
#ifndef B_Included
#define B_Included

#include "A.h"

class B {};

void MyOtherFunction(A argument);
#endif

现在,如果我尝试#include "A.h",那么它会扩展到

// File: A.h
#ifndef A_Included
#define A_Included

#include "B.h"

class A {};

void MyFunction(B argument);
#endif

当我尝试展开#include "B.h"时,我明白了:

// File: A.h
#ifndef A_Included
#define A_Included

// File: B.h
#ifndef B_Included
#define B_Included

#include "A.h"

class B {};

void MyOtherFunction(A argument);
#endif

class A {};

void MyFunction(B argument);
#endif

此时,预处理器将再次尝试展开A.h,这导致了这一点:

// File: A.h
#ifndef A_Included
#define A_Included

// File: B.h
#ifndef B_Included
#define B_Included

// File: A.h
#ifndef A_Included
#define A_Included

#include "B.h"

class A {};

void MyFunction(B argument);
#endif

class B {};

void MyOtherFunction(A argument);
#endif

class A {};

void MyFunction(B argument);
#endif

现在,让我们看看当我们解决所有这些奇怪的包括警卫时会发生什么。我们第一次看到A时,它已经扩展了,就像我们第一次扩展B的情况一样。但是,当我们第二次看到A时,它根本没有展开。因此,在取出注释和预处理器指令之后,我们得到了这个结果代码:

class B {};
void MyOtherFunction(A argument);
class A {};
void MyFunction(B argument);

请注意,当声明MyOtherFunction时,尚未声明A,因此编译器报告错误。

要解决此问题,您可以在需要它们的头文件中转发声明AB

// File: A.h
#ifndef A_Included
#define A_Included

class A {};
class B;    // Forward declaration

void MyFunction(B argument);
#endif

// File: B.h
#ifndef B_Included
#define B_Included

class B {};
class A;    // Forward declaration

void MyFunction(B argument);
#endif

现在,没有更多的循环依赖。只要你{。1}} .cpp文件中的相应头文件,你应该没问题。

希望这有帮助!