ошибка: ожидаемое имя класса до токена ‘{’ - PullRequest
39 голосов
/ 16 марта 2011

Я знаю, что есть пара похожих вопросов (включая циклический) из 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'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_ */

ОБНОВЛЕНИЕ:

Я включил Landing.h из-за вызова конструктора Landing в методе Event :: createNewLanding:

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

Ответы [ 3 ]

80 голосов
/ 16 марта 2011

Это должен быть комментарий, но комментарии не допускают многострочный код.

Вот что происходит:

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 - Event? Я еще не слышал о Event».

24 голосов
/ 16 марта 2011

Заменить

#include "Landing.h"

с

class Landing;

Если вы все еще получаете ошибки, также отправьте Item.h, Flight.h и common.h

РЕДАКТИРОВАТЬ: в ответ на комментарий.

Вам понадобится, например, #include "Landing.h" из Event.cpp для фактического использования класса. Вы просто не можете включить его из Event.h

3 голосов
/ 16 марта 2011

Если вы заранее объявите Flight и Landing в Event.h, то вы должны быть исправлены.

Не забудьте #include "Flight.h" и #include "Landing.h" в файле реализации для Event.

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

...