error: expected class-name before ‘{’ token

来源:互联网 发布:搜索引擎优化bwysj 编辑:程序博客网 时间:2024/06/09 16:36

I know there are a couple of similar questions(circular include) out stackoverflow and other websites. But I still can't figure it out and no solutions pop out. So I would like to post my specific one.

I have a Event class who has 2 and actually more subclass, which are Arrival and Landing. The compiler(g++) complains:

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

People said that it's a circular include. The 3 header files(Event.h Arrival.h Landing.h) are as follows:

the 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 infoprivate:    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:

I included Landing.h due to Landing's constructor is called in the Event::createNewLanding method:

Landing* Event::createNewLanding(Arrival* arrival) {    return new Landing(flight, time + Landing::PERMISSION_TIME);}
share|improve this question

78% accept rate
 
1 
According to the compiler output, your error is in Landing.h (on line 13). Why did you put a comment inEvent.h saying the error was there? – Ben Voigt Mar 16 '11 at 1:13
 
@Ben Voigt sorry, I've changed it – draw Mar 16 '11 at 1:21
Was this post useful to you?     

3 Answers

activeoldestvotes
up vote8down voteaccepted

Replace

#include "Landing.h"

with

class Landing;

If you still get errors, also post Item.hFlight.h and common.h

EDIT: In response to comment.

You will need to e.g. #include "Landing.h" from Event.cpp in order to actually use the class. You just cannot include it from Event.h

share|improve this answer
 
because I called Landing's constructor: Landing* Event::createNewLanding(Arrival* arrival) { return new Landing(flight, time + Landing::PERMISSION_TIME); } – draw Mar 16 '11 at 1:22
2 
#include the needed header files in your .cpp not your .h – Erik Mar 16 '11 at 1:23
 
that works. Thank you so much. Another question: does that implies that it's a good practice to always make foreword reference in you header file? – draw Mar 16 '11 at 1:30
 
@draw: It's good practice to forward declare when forward declaration is enough (you only need Type * orType &)- in addition to avoiding such circular include problems, this reduces interdependencies in between files, which a.o. reduces compile time. – Erik Mar 16 '11 at 1:34
 
thanks a lot! – draw Mar 16 '11 at 3:21
feedback
up vote0down vote

If you forward-declare Flight and Landing in Event.h, then you should be fixed.

Remember to #include "Flight.h" and #include "Landing.h" in your implementation file forEvent.

The general rule of thumb is: if you derive from it, or compose from it, or use it by value, the compiler must know its full definition at the time of declaration. If you compose from a pointer-to-it, the compiler will know how big a pointer is. Similarly, if you pass a reference to it, the compiler will know how big the reference is, too.

share|improve this answer
 
1 
#include <privateheader.h> is generally incorrect - Use "privateheader.h" – Erik Mar 16 '11 at 1:14
feedback
up vote11down vote

This should be a comment, but comments don't allow multi-line code.

Here's what's happening:

in Event.cpp #include "Event.h"

preprocessor starts processing Event.h

#ifndef EVENT_H_

it isn't defined yet, so keep going

#define EVENT_H_#include "common.h"

common.h gets processed ok

#include "Item.h"

Item.h gets processed ok

#include "Flight.h"

Flight.h gets processed ok

#include "Landing.h"

preprocessor starts processing Landing.h

#ifndef LANDING_H_

not defined yet, keep going

#define LANDING_H_#include "Event.h"

preprocessor starts processing Event.h

#ifndef EVENT_H_

This IS defined already, the whole rest of the file gets skipped. Continuing with Landing.h

class Landing: public Event {

The preprocessor doesn't care about this, but the compiler goes "WTH is Event? I haven't heard aboutEvent yet."

share|improve this answer
 
+1 vote. thank you too. your hint is systematic and useful. – draw Mar 16 '11 at 1:35
feedback

Your Answer

 
log in
or

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged c++ g++ or ask your own question.

原创粉丝点击