Error: ожидаемое имя класса перед '{токеном
Я знаю, что есть несколько аналогичных вопросов (включая циркуляр) из stackoverflow и других сайтов. Но я до сих пор не могу понять, и никаких решений не вышло. Поэтому я хотел бы опубликовать свой конкретный вариант.
У меня есть класс Event, у которого есть 2 и фактически больше подкласса, которые являются Прибытием и Посадкой. Компилятор (g++) жалуется:
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
Люди говорили, что это круговой поток. 3 файла заголовка (Event.h Arrival.h Landing.h) выглядят следующим образом:
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 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_ */
UPDATE:
Я включил Landing.h из-за конструктора Landing в методе Event:: createNewLanding:
Landing* Event::createNewLanding(Arrival* arrival) {
return new Landing(flight, time + Landing::PERMISSION_TIME);
}
Ответы
Ответ 1
Заменить
#include "Landing.h"
с
class Landing;
Если вы все еще получаете ошибки, также отправляйте Item.h
, Flight.h
и common.h
EDIT: в ответ на комментарий.
Вам нужно будет, например, #include "Landing.h"
от Event.cpp
, чтобы фактически использовать класс. Вы просто не можете включить его из Event.h
Ответ 2
Это должен быть комментарий, но комментарии не допускают многострочный код.
Вот что происходит:
in Event.cpp
#include "Event.h"
Препроцессор начинает обработку Event.h
#ifndef EVENT_H_
пока не определено, поэтому продолжайте движение
#define EVENT_H_
#include "common.h"
common.h
обрабатывается нормально
#include "Item.h"
Item.h
обрабатывается нормально
#include "Flight.h"
Flight.h
обрабатывается нормально
#include "Landing.h"
препроцессор начинает обработку Landing.h
#ifndef LANDING_H_
еще не определено, продолжайте движение
#define LANDING_H_
#include "Event.h"
Препроцессор начинает обработку Event.h
#ifndef EVENT_H_
Это уже определено, весь остальной файл пропущен. Продолжение с Landing.h
class Landing: public Event {
Препроцессор не заботится об этом, но компилятор идет "WTH is Event
? Я еще не слышал о Event
.
Ответ 3
Если вы переадресовываете Flight
и Landing
в Event.h
, то вы должны быть исправлены.
Помните #include "Flight.h"
и #include "Landing.h"
в файле реализации Event
.
Общее эмпирическое правило: если вы выходите из него или сочиняете его или используете его по значению, компилятор должен знать его полное определение во время объявления. Если вы составите из указателя к нему, компилятор будет знать, насколько большой указатель. Аналогично, если вы передадите ссылку на него, компилятор будет знать, насколько велика эта ссылка.