C++ 错误:“{”标记之前的预期类名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5319906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: expected class-name before ‘{’ token
提问by draw
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.
我知道在 stackoverflow 和其他网站上有几个类似的问题(圆形包括)。但我仍然无法弄清楚,也没有解决方案出现。所以我想发布我的具体一个。
I have a Event class who has 2 and actually more subclass, which are Arrival and Landing. The compiler(g++) complains:
我有一个事件类,它有 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
People said that it's a circular include. The 3 header files(Event.h Arrival.h Landing.h) are as follows:
人们说这是一个循环包含。3个头文件(Event.h Arrival.h Landing.h)如下:
the Event.h:
事件.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:
到达.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
登陆.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:
由于在 Event::createNewLanding 方法中调用了 Landing 的构造函数,因此我包含了 Landing.h:
Landing* Event::createNewLanding(Arrival* arrival) {
return new Landing(flight, time + Landing::PERMISSION_TIME);
}
采纳答案by Erik
Replace
代替
#include "Landing.h"
with
和
class Landing;
If you still get errors, also post Item.h
, Flight.h
and common.h
如果仍然出现错误,也张贴Item.h
,Flight.h
并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
您需要例如#include "Landing.h"
fromEvent.cpp
才能实际使用该类。你只是不能包括它Event.h
回答by Ben Voigt
This should be a comment, but comments don't allow multi-line code.
这应该是注释,但注释不允许多行代码。
Here's what's happening:
这是发生了什么:
in Event.cpp
在 Event.cpp
#include "Event.h"
preprocessor starts processing Event.h
预处理器开始处理 Event.h
#ifndef EVENT_H_
it isn't defined yet, so keep going
它还没有定义,所以继续
#define EVENT_H_
#include "common.h"
common.h
gets processed ok
common.h
处理好
#include "Item.h"
Item.h
gets processed ok
Item.h
处理好
#include "Flight.h"
Flight.h
gets processed ok
Flight.h
处理好
#include "Landing.h"
preprocessor starts processing Landing.h
预处理器开始处理 Landing.h
#ifndef LANDING_H_
not defined yet, keep going
还没有定义,继续
#define LANDING_H_
#include "Event.h"
preprocessor starts processing Event.h
预处理器开始处理 Event.h
#ifndef EVENT_H_
This IS defined already, the whole rest of the file gets skipped. Continuing with Landing.h
这已经定义了,文件的其余部分被跳过。继续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."
预处理器不关心这个,但编译器会说“WTH 是Event
?我还没有听说过Event
。”
回答by Andy Finkenstadt
If you forward-declare Flight
and Landing
in Event.h
, then you should be fixed.
如果您提前声明Flight
并Landing
在 中Event.h
,那么您应该得到修复。
Remember to #include "Flight.h"
and #include "Landing.h"
in your implementation file for Event
.
请记住,#include "Flight.h"
并#include "Landing.h"
为您的实现文件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.
一般的经验法则是:如果你从它派生,或从它组合,或按值使用它,编译器必须在声明时知道它的完整定义。如果您从指向它的指针组合,编译器将知道一个指针有多大。同样,如果你传递一个引用,编译器也会知道这个引用有多大。
回答by Ali80
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.
我在我的头文件中使用了命名空间并且忘记了右括号,而是得到了这个神秘的错误。
回答by Alberto
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.
我知道回答这个问题有点晚,但它是google的第一个条目,所以我认为值得回答。
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
.
您已经创建了一个接口class Event: public Item
来定义所有事件应该实现的方法。然后你定义了两种类型的事件,它们继承自class Event: public Item
; 到达和着陆,然后,您Landing* createNewLanding(Arrival* arrival);
从class Event: public Item
界面中的着陆功能添加了一个方法。你应该把这个方法移到class Landing: public Event
类中,因为它只对着陆有意义。class Landing: public Event
和class Arrival: public Event
class 应该知道class Event: public Item
但 event 不应该知道class Landing: public Event
也不class Arrival: public Event
。
I hope this helps, regards, Alberto
我希望这会有所帮助,问候,阿尔贝托