Подтвердить что ты не робот

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);
}
4b9b3361

Ответ 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.

Общее эмпирическое правило: если вы выходите из него или сочиняете его или используете его по значению, компилятор должен знать его полное определение во время объявления. Если вы составите из указателя к нему, компилятор будет знать, насколько большой указатель. Аналогично, если вы передадите ссылку на него, компилятор будет знать, насколько велика эта ссылка.