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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:54:27  来源:igfitidea点击:

error: expected class-name before ‘{’ token

c++g++

提问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.hand common.h

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

EDIT: In response to comment.

编辑:回应评论。

You will need to e.g. #include "Landing.h"from Event.cppin 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.hgets processed ok

common.h处理好

#include "Item.h"

Item.hgets processed ok

Item.h处理好

#include "Flight.h"

Flight.hgets 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 Eventyet."

预处理器不关心这个,但编译器会说“WTH 是Event?我还没有听说过Event。”

回答by Andy Finkenstadt

If you forward-declare Flightand Landingin Event.h, then you should be fixed.

如果您提前声明FlightLanding在 中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 Itemto 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 Iteminterface. You should move this method to the class Landing: public Eventclass because it only has sense for a landing. class Landing: public Eventand class Arrival: public Eventclass should know class Event: public Itembut event should not know class Landing: public Eventnor 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 Eventclass Arrival: public Eventclass 应该知道class Event: public Item但 event 不应该知道class Landing: public Event也不class Arrival: public Event

I hope this helps, regards, Alberto

我希望这会有所帮助,问候,阿尔贝托