2011-03-16 91 views
30

我知道有几个类似的问题(通告包括)出栈计算器和其他网站。但我仍然无法弄清楚,没有解决方案。所以我想发布我的具体内容。错误:在'{'令牌之前预期的类名

我有一个Event类,它有2个实际上更多的子类,它们是Arrival和Landing。编译器(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_ */ 

UPDATE:

我公司luded Landing.h由于着陆的构造函数被调用的事件:: createNewLanding方法:

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

根据编译器输出,你的错误在'Landing.h'中(在第13行)。为什么你在'Event.h'中发表评论说错误在那里? – 2011-03-16 01:13:43

+0

@Ben Voigt对不起,我改变了它 – draw 2011-03-16 01:21:22

回答

21

更换

#include "Landing.h" 

class Landing; 

如果仍然出现错误,也张贴Item.hFlight.hcommon.h

编辑:回应评论。

您将需要#include "Landing.h"Event.cpp为了实际使用这个类。你不能从Event.h

+0

,因为我叫Landing的构造函数:Landing * Event :: createNewLanding(Arrival * arrival){return new Landing(flight,time + Landing :: PERMISSION_TIME); # – draw 2011-03-16 01:22:04

+3

'#include'需要的头文件*在你的.cpp *中,而不是你的.h – Erik 2011-03-16 01:23:07

+0

。非常感谢。另一个问题:这是否意味着总是在你的头文件中做前言引用是一个好习惯? – draw 2011-03-16 01:30:58

2

包括在Event.h如果向前声明FlightLanding,那么你就应该是固定的。

请记住在您的实施文件中的#include "Flight.h"#include "Landing.h"Event

一般的经验法则是:如果你从它派生出来,或者由它构成,或者按值使用它,编译器在声明时必须知道它的完整定义。如果你从一个指针指向它,编译器会知道指针有多大。同样,如果你传递一个引用,编译器也会知道引用的大小。

+1

'#include '通常是不正确的 - 使用'“privateheader.h”' – Erik 2011-03-16 01:14:38

74

这应该是一个评论,但评论不允许多行代码。

这里发生的事情:

Event.cpp

#include "Event.h" 

预处理开始Event.h

#ifndef EVENT_H_ 

它尚未定义的处理,所以坚持下去

#define EVENT_H_ 
#include "common.h" 

common.h得到处理确定

#include "Item.h" 

Item.h得到处理确定

#include "Landing.h" 

预处理器开始处理

#include "Flight.h" 

Flight.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呢。”

+0

@Ben如果我们使用'class Landing'而不是'#include ',将定义'Landing'两次?如果预处理器不跳过'#ifndef LANDING_H_',它如何对待'class Landing'?按照定义或不? – 2015-11-05 21:12:27

+1

@MiloLu:这就是为什么你使用前向声明'class Landing;'这不是一个定义('{}'中没有主体)。 – 2015-11-06 15:11:58

相关问题