error: expected class-name before ‘{’ token

C++G++

C++ Problem Overview


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.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

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

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

C++ Solutions


Solution 1 - C++

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 about Event yet."

Solution 2 - C++

Replace

#include "Landing.h"

with

class Landing;

If you still get errors, also post Item.h, Flight.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

Solution 3 - C++

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 for Event.

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.

Solution 4 - C++

I know it is a bit late to answer this question, but it is the first entry in google, so I think it is worth to answer it.

The problem is not a coding problem, it is an architecture problem.

You have created an interface class Event: public Item to define the methods which all events should implement. Then you have defined two types of events which inherits from class Event: public Item; Arrival and Landing and then, you have added a method Landing* createNewLanding(Arrival* arrival); from the landing functionality in the class Event: public Item interface. You should move this method to the class Landing: public Event class because it only has sense for a landing. class Landing: public Event and class Arrival: public Event class should know class Event: public Item but event should not know class Landing: public Event nor class Arrival: public Event.

I hope this helps, regards, Alberto

Solution 5 - C++

I got the same error with a different problem,

I used namespaces in my headers and forgot the closing bracket and got this cryptic error instead.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondrawView Question on Stackoverflow
Solution 1 - C++Ben VoigtView Answer on Stackoverflow
Solution 2 - C++ErikView Answer on Stackoverflow
Solution 3 - C++Andy FinkenstadtView Answer on Stackoverflow
Solution 4 - C++AlbertoView Answer on Stackoverflow
Solution 5 - C++Ali80View Answer on Stackoverflow