2011-03-16 17 views
30

Sé que hay un par de preguntas similares (circular incluir) a stackoverflow y otros sitios web. Pero aún no puedo resolverlo y no aparecen soluciones. Entonces me gustaría publicar mi específico.error: class-name esperado antes de '{' token

Tengo una clase de evento que tiene 2 y en realidad más subclase, que son Llegada y aterrizaje. El compilador (g ++) se queja:

g++ -c -Wall -g -DDEBUG Event.cpp -o Event.o 
In file included from Event.h:15, 
       from Event.cpp:8: 
Landing.h:13: error: expected class-name before ‘{’ token 
make: *** [Event.o] Error 1 

La gente dijo que se trata de una circular incluyen. Los 3 archivos de cabecera (Event.h Arrival.h Landing.h) son los siguientes:

la Event.h:

#ifndef EVENT_H_ 
#define EVENT_H_ 

#include "common.h" 
#include "Item.h" 
#include "Flight.h" 

#include "Landing.h" 

class Arrival; 

class Event : public Item { 
public: 
    Event(Flight* flight, int time); 
    virtual ~Event(); 

    virtual void occur() = 0; 
    virtual string extraInfo() = 0; // extra info for each concrete event 

    // @implement 
    int compareTo(Comparable* b); 
    void print(); 

protected: 
    /************** this is why I wanna include Landing.h *******************/ 
    Landing* createNewLanding(Arrival* arrival); // return a Landing obj based on arrival's info 

private: 
    Flight* flight; 
    int time; // when this event occurs 

}; 

#endif /* EVENT_H_ */ 

Arrival.h:

#ifndef ARRIVAL_H_ 
#define ARRIVAL_H_ 

#include "Event.h" 

class Arrival: public Event { 
public: 
    Arrival(Flight* flight, int time); 
    virtual ~Arrival(); 

    void occur(); 
    string extraInfo(); 
}; 

#endif /* ARRIVAL_H_ */ 

Landing.h

#ifndef LANDING_H_ 
#define LANDING_H_ 

#include "Event.h" 

class Landing: public Event {/************** g++ complains here ****************/ 
public: 
    static const int PERMISSION_TIME; 

    Landing(Flight* flight, int time); 
    virtual ~Landing(); 

    void occur(); 
    string extraInfo(); 
}; 

#endif /* LANDING_H_ */ 

ACTUALIZACIÓN:

I inc luded Landing.h debido al constructor de aterrizaje se llama en el Evento :: createNewLanding método:

Landing* Event::createNewLanding(Arrival* arrival) { 
    return new Landing(flight, time + Landing::PERMISSION_TIME); 
} 
+1

De acuerdo con la salida del compilador, el error está en 'Landing.h' (en la línea 13). ¿Por qué pusiste un comentario en 'Event.h' diciendo que el error estaba allí? –

+0

@Ben Voigt lo siento, he cambiado – draw

Respuesta

21

Reemplazar

#include "Landing.h" 

con

class Landing; 

Si continúa recibiendo errores, también publicar Item.h , Flight.h y common.h

EDITAR: En respuesta al comentario.

Necesitarás, por ejemplo, #include "Landing.h" de Event.cpp para usar realmente la clase. Usted simplemente no puede incluirlo desde Event.h

+0

porque llamé al constructor de aterrizaje: Aterrizaje * Evento :: createNewLanding (llegada * llegada) {return new Landing (vuelo, hora de aterrizaje + :: PERMISSION_TIME); } – draw

+3

'# include' los archivos de encabezado necesarios * en su .cpp * no su .h – Erik

+0

que funciona. Muchas gracias. Otra pregunta: ¿eso implica que es una buena práctica hacer siempre una referencia previa en su archivo de encabezado? – draw

2

Si prospectivas declara Flight y Landing en Event.h, entonces usted debe ser fijo.

Recuerde #include "Flight.h" y #include "Landing.h" en su archivo de implementación para Event.

La regla general es: si deriva de ella, o la compone, o la usa por valor, el compilador debe conocer su definición completa en el momento de la declaración. Si compones desde un puntero a él, el compilador sabrá qué tan grande es un puntero. De forma similar, si le pasa una referencia, el compilador sabrá qué tan grande es la referencia, también.

+1

'# include ' es generalmente incorrecta - Use ' "privateheader.h"' – Erik

74

Esto debería ser un comentario, pero los comentarios no permiten el código de varias líneas.

Esto es lo que está pasando:

en Event.cpp

#include "Event.h" 

preprocesador inicia el procesamiento Event.h

#ifndef EVENT_H_ 

que aún no está definido, por lo que seguir adelante

#define EVENT_H_ 
#include "common.h" 

common.h se procesa bien

#include "Item.h" 

Item.h se procesa bien

#include "Flight.h" 

Flight.h se procesa bien

#include "Landing.h" 

preprocesador empieza a procesar Landing.h

#ifndef LANDING_H_ 

no definido aún, seguir adelante comienza

#define LANDING_H_ 

#include "Event.h" 

preprocesador procesamiento Event.h

#ifndef EVENT_H_ 

esto se define ya, todo el resto del archivo se omite. Continuando con Landing.h

class Landing: public Event { 

El preprocesador no se preocupa de esto, pero el compilador va "WTH es Event? No he oído hablar de Event todavía."

+0

@Ben Si utilizamos clase 'Landing' en lugar de' # include "Landing.h" ',' se puede definir Landing' ¿dos veces?Si el preprocesador no omite '#ifndef LANDING_H_', ¿cómo trata' landing de la clase'? Según lo definido o no? –

+1

@MiloLu: Es por eso que utilizas una declaración directa 'clase Landing;' que no es una definición (no body en '{}'). –

Cuestiones relacionadas