2011-06-29 9 views
7

Por lo tanto, espero que esto termine siendo una respuesta simple, pero he estado pirateando por un tiempo, y no puedo para arreglar este problema Así que tengo una clase en particular, Intersection, que cuando se incluye en cualquier otra cabecera me da:Encabezado creado por el usuario Causa C2061: Error de sintaxis: Identificador 'nombre de clase'

error C2061: syntax error : identifier 'Intersection'

Este es mi cabecera Intersección:

#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 

Ahora, si intento utilizar esta clase en otro lugar, obtengo el error. Por ejemplo:

#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 

Particularmente en el Road constructor (y cualquier otras clases que se hace referencia Intersection). No creo que sea un problema de sintaxis, ya que Coord es otra clase, definida de la misma manera, y el compilador (VS 2008) no se queja de ello. Es solo Intersection en particular, lo que me está causando problemas. :/

Lo estoy etiquetando como tarea, es para lo que es, aunque esto no es más que un error del que no me puedo deshacer en lugar de ser parte del problema.

¿Pensamientos?

+2

Parece que necesita reenviar declarar 'clase Intersección;' en el archivo ROAD_H. – GWW

+0

Interesante. Eso parece haberlo hecho. ¿Podría explicar por qué funciona al incluir todo el encabezado no, y por qué solo esa clase parece tener un problema? Hazlo en una respuesta y con mucho gusto te daré el cheque. :) – kcoppock

Respuesta

25

Parece que el error es que tiene dos archivos de encabezado que se incluyen circularmente entre sí: intersection.hy road.h. Hacer esto tiende a provocar sorpresas extrañas en C++ debido a cómo funcionan los guardias. Por ejemplo, supongamos que tengo dos ficheros de cabecera que se ven así:

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

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

y

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

#include "A.h" 

class B {}; 

void MyOtherFunction(A argument); 
#endif 

Ahora, si trato de #include "A.h", a continuación, se expande a

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

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

Cuando intento expandir el #include "B.h", obtengo esto:

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

En este punto, el preprocesador volverá a intentar la expansión hacia fuera A.h, lo que lleva a esto:

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

Ahora, vamos a ver lo que sucede cuando resolvemos todos estos extraños incluyen guardias. La primera vez que vemos A, se expande, como es el caso cuando expandimos B por primera vez. Sin embargo, cuando vemos A por segunda vez, no se expande en absoluto. Por lo tanto, después de sacar los comentarios y las directivas del preprocesador, obtenemos el código resultante:

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

Tenga en cuenta que cuando se declara MyOtherFunction, A aún no ha sido declarada, por lo que el compilador informa de un error.

Para solucionar este problema, puede reenviar-declara A y B en los ficheros de cabecera que los necesitan:

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

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

void MyFunction(B argument); 
#endif 

y

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

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

void MyFunction(B argument); 
#endif 

Ahora, ya no hay más dependencias circulares. Siempre y cuando #include los archivos de cabecera apropiados en los archivos .cpp, debería estar bien.

Espero que esto ayude!

+0

¡Maldición! Esta es una gran respuesta también; gracias por profundizar en eso. Estoy increíblemente oxidado en C++ (me he centrado en Java), así que este es un buen repaso. ¡Gracias! – kcoppock

+0

¡Has salvado mi día! –

Cuestiones relacionadas