【问题标题】:error: expected class-name before ‘{’ token错误:“{”标记之前的预期类名
【发布时间】:2021-09-22 04:25:41
【问题描述】:

我知道在 stackoverflow 和其他网站上有几个类似的问题(循环包括)。但我仍然无法弄清楚,也没有解决方案弹出。所以我想发布我的具体内容。

我有一个 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_ */

到达.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_ */

着陆.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_ */

更新:

我包含 Landing.h 是因为在 Event::createNewLanding 方法中调用了 Landing 的构造函数:

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

【问题讨论】:

  • 根据编译器输出,您的错误在 Landing.h (第 13 行)。你为什么要在Event.h 中发表评论说存在错误?
  • @Ben Voigt 抱歉,我已经改了

标签: c++ g++


【解决方案1】:

替换

#include "Landing.h"

class Landing;

如果您仍然遇到错误,请同时发布 Item.hFlight.hcommon.h

编辑:回应评论。

您将需要例如#include "Landing.h" 来自Event.cpp,以便实际使用该类。您只是不能从Event.h 中包含它

【讨论】:

  • 因为我调用了 Landing 的构造函数: Landing* Event::createNewLanding(Arrival*arrival) { return new Landing(flight, time + Landing::PERMISSION_TIME); }
  • #include 所需的头文件在你的.cpp而不是你的.h
  • 行得通。太感谢了。另一个问题:这是否意味着始终在头文件中引用前言是一种好习惯?
  • @draw:当转发声明足够时转发声明是一种很好的做法(您只需要Type *Type &)- 除了避免此类循环包含问题外,这还减少了文件之间的相互依赖关系, 其中 a减少编译时间。
  • 听评论!将#include 放入您的.cpp,而不是您的.h!这就是为我解决的问题。您仍然需要确保您的 .h 文件是 #included 以便其他人定义的文件更低。此外,如之前的 cmets 所述,您可以使用类的前向声明来帮助循环定义任何内容。
【解决方案2】:

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

记住#include "Flight.h"#include "Landing.h"Event 的实现文件中。

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

【讨论】:

  • #include <privateheader.h> 通常不正确 - 使用 "privateheader.h"
【解决方案3】:

这应该是注释,但是 cmets 不允许多行代码。

这是发生了什么:

Event.cpp

#include "Event.h"

预处理器开始处理Event.h

#ifndef EVENT_H_

还没有定义,继续往下看

#define EVENT_H_
#include "common.h"

common.h 处理正常

#include "Item.h"

Item.h 处理正常

#include "Flight.h"

Flight.h 处理正常

#include "Landing.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。”

【讨论】:

  • @Ben 如果我们使用class Landing 而不是#include "Landing.h"Landing 会被定义两次吗?如果预处理器不跳过#ifndef LANDING_H_,它如何处理class Landing?定义与否?
  • @MiloLu:这就是为什么你使用前向声明 class Landing; 这不是定义({} 中没有正文)。
【解决方案4】:

我遇到了同样的错误,但问题不同,

我在标题中使用了命名空间,但忘记了右括号并得到了这个神秘的错误。

【讨论】:

    【解决方案5】:

    我知道回答这个问题有点晚,但它是google的第一个条目,所以我认为值得回答。

    问题不是编码问题,而是架构问题。

    您已经创建了一个接口class Event: public Item 来定义所有事件应该实现的方法。然后你定义了两种继承自class Event: public Item 的事件; Arrival and Landing 然后,您从class Event: public Item 接口的登陆功能中添加了一个方法Landing* createNewLanding(Arrival* arrival);。您应该将此方法移至class Landing: public Event 类,因为它只对着陆有意义。 class Landing: public Eventclass Arrival: public Event 类应该知道 class Event: public Item 但事件不应该知道 class Landing: public Eventclass Arrival: public Event

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

    【讨论】:

      猜你喜欢
      • 2015-01-19
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多