2011-06-29 14 views
7

これは単純な回答に終わると期待していますが、今はしばらくハッキングしているようですこの問題を解決するC2061でユーザー作成のヘッダーが発生する:構文エラー:識別子 'classname'

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 

、私はこのクラスを使用しようとすると、だから私は、他のヘッダに含まが私を与えたときに、Intersection、特定のクラスを持っています他の場所では、エラーが発生します。例えば:

#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というのは私にこの問題を与えているだけです。 :/

私はそれを宿題とタグ付けしています。これはそれが問題ですが、これは単なるエラーではありますが、問題の一部ではなく取り除くことはできません。

思考?

+2

ROAD_Hファイルで 'class Intertersection; 'を宣言する必要があるようです。 – GWW

+0

興味深い。それはそれをしたようだ。ヘッダー全体を含めても動作しない理由と、そのクラスだけに問題があるように見える理由を説明できますか?答えでそれをしてください、私は喜んであなたにチェックを与えるでしょう。 :) – kcoppock

答えて

25

これは、循環的に2つのヘッダファイル(intersection.hとroad.h)があるというエラーです。これを行うと、警備員がどのように働くかのために、C++の奇妙な驚きにつながる傾向があります。私は#include "A.h"しようとすると、それは

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

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

に出て拡張し、今

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

:たとえば、私はこのように見える2つのヘッダファイルがあるとし#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を2回目に見ると、全く展開されません。 MyOtherFunctionが宣言されたときに、Aがまだ宣言されていない、ので、コンパイラはエラーを報告することを

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

は注意:このように、コメントやプリプロセッサディレクティブを取り出した後、我々はこの結果のコードを取得します。

これを修正するには、あなたはそれらを必要とするヘッダファイル内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 

は今、これ以上の循環依存があります。あなたが #include .cppファイルの適切なヘッダーファイルである限り、あなたはうまくいくはずです。

希望すると便利です。

+0

くそー!これは素晴らしい答えです。それについて深く考えてくれてありがとう。私はC++で信じられないほど錆びています(Javaに焦点を当てています)ので、これは良いリフレッシャーです。ありがとうございました! – kcoppock

+0

あなたは、私の一日を救った! –