導致 C2061 的用戶創建的標頭:語法錯誤:標識符“類名” (User-Created Header Causing C2061: Syntax Error : Identifier 'classname')


問題描述

導致 C2061 的用戶創建的標頭:語法錯誤:標識符“類名” (User-Created Header Causing C2061: Syntax Error : Identifier 'classname')

So, I sort of expect this to end up being a simple answer, but I've been hacking at it for a while now, and can't seem to fix this issue. So I have a particular class, Intersection, that when included in any other header gives me:

error C2061: syntax error : identifier 'Intersection'

This is my Intersection header:

#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

Now, if I attempt to use this class elsewhere, I get the error. For example:

#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

Particularly at the Road constructor (and any other classes which reference Intersection). I don't think it's a syntax problem, as Coord is another class, defined in the same manner, and the compiler (VS 2008) doesn't complain about it. It's just Intersection in particular that's giving me this trouble. :/

I'm tagging it homework -- it's what it's for, even though this is just an error I can't get rid of rather than part of the problem.

Thoughts?


參考解法

方法 1:

It looks like the error is that you have two header files that are circularly including one another - intersection.h and road.h.  Doing this tends to lead to weird surprises in C++ because of how include guards work.  For example, suppose that I have two header files that look like this:

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

#include "B.h"

class A {};

void MyFunction(B argument);
#endif

and

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

#include "A.h"

class B {};

void MyOtherFunction(A argument);
#endif

Now, if I try to #include "A.h", then it expands out to

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

#include "B.h"

class A {};

void MyFunction(B argument);
#endif

When I try expanding out the #include "B.h", I get this:

// 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

At this point, the preprocessor will again try expanding out A.h, which leads to this:

// 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

Now, let's see what happens when we resolve all of these weird include guards.  The first time we see A, it's expanded out, as is the case when we expand out B for the first time.  However, when we see A for the second time, it's not expanded out at all.  Thus, after taking out comments and preprocessor directives, we get this resulting code:

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

Notice that when MyOtherFunction is declared, A has not yet been declared, and so the compiler reports an error.

To fix this, you can forward-declare A and B in the header files that need them:

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

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

void MyFunction(B argument);
#endif

and

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

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

void MyFunction(B argument);
#endif

Now, there are no more circular dependencies.  As long as you #include the appropriate header files in the .cpp files, you should be fine.

Hope this helps!

(by Kevin Coppocktemplatetypedef)

參考文件

  1. User-Created Header Causing C2061: Syntax Error : Identifier 'classname' (CC BY-SA 3.0/4.0)

#syntax-error #C++






相關問題

SQL Server 2008 - 嘗試編輯日期 - 語法錯誤? (SQL Server 2008 - Trying to edit dates - Syntax Error?)

將 Jquery.min 升級到 Jquery.1.9 時出錯 (Error Upgrade Jquery.min into Jquery.1.9)

SyntaxError:無效語法(打印功能) (SyntaxError: invalid syntax (print function))

錯誤:“if”之前的預期表達式 (error: expected expression before ‘if’)

導致 C2061 的用戶創建的標頭:語法錯誤:標識符“類名” (User-Created Header Causing C2061: Syntax Error : Identifier 'classname')

If 語句行收到語法錯誤 (Syntax Error received on If statement line)

語法錯誤:到達了意外的文件結尾。你有一個未關閉的#if (Syntax error: Unexpected end of file reached. You have an unclosed #if)

已經放 } 但錯誤仍然說 } 是預期的? (Already put } but the error still says that } is expected?)

為什麼 Java 不允許在這裡使用三元運算符? (Why doesn't Java allow the use of a ternary operator here?)

我在繪製向量時遇到語法錯誤 (I'm encountering a syntax error while plotting vectors)

我想在 Kotlin 中自定義新按鈕時遇到問題 (I have a problem when I want to customize my new button in Kotlin)

為什麼帶註釋的變量不能是全局的? (Why can't an annotated variable be global?)







留言討論