【问题标题】:Qt ISO C++ forbids declaration without type - header file is included?Qt ISO C++ 禁止声明没有类型 - 包含头文件?
【发布时间】:2011-04-18 13:09:29
【问题描述】:

在我正在处理的 Qt 应用程序中,我收到了没有类型错误的禁止声明。问题是我已经包含了声明类的头文件。据我所知,它应该被定义为一种类型。我也尝试过前向声明,但我想在这个文件中使用类的方法,所以我需要整个头文件。 代码:

Shapes.h

#ifndef SHAPES_H
#define SHAPES_H

#include "Colors.h"
#include <QPoint>
#include "glwidget.h"

//class GLWidget;  

class Shape
{
    public:

        virtual void draw();
};

class Rectangle : public Shape
{
    public:
        Rectangle(GLWidget *w, QPoint tl, QPoint br);

        virtual void draw(){
              // top horizontal
            for(int i = topLeft.x(); i < btmRight.x(); i++){
                 glWidget->setPixel(i,topLeft.y(), color);
             }
        }

    private:
        QPoint topLeft,btmRight;
        GLWidget *glWidget;        /****  This is the Error line  ****/
        RGBColor color;
};

#endif // SHAPES_H

glwidget.h:

#ifndef AGLWIDGET_H
#define AGLWIDGET_H

#include <QGLWidget>

#include "Colors.h"
#include "Shapes.h"

class GLWidget : public QGLWidget
{
    Q_OBJECT

public:
    GLWidget(QWidget *parent = 0);
    ~GLWidget();

    QSize minimumSizeHint() const;
    QSize sizeHint() const;

    void setPixel(int x, int y, RGBColor c);

public slots:
    void setColor(RGBColor c);
    void setDrawRectangle();



protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);

private:

    QPoint lastPos;
    QVector<QPoint> drawPoints;
    RGBColor paintColor;
    int drawmode;
    Shape *currentShape;

};


#endif

我不明白为什么我不能在 Shapes.h 中使用我的 GLWidget。错误出现在我声明 GLWidget *glWidget; 行的 Shapes.h 中。 如果我使用前向声明,即。类 GLWidget;这个错误消失了,但我实际上不能像在 Rectangle.draw() 中那样使用 GLWidget 方法

任何人都知道为什么编译器不会将 GLWidget 视为 Shapes.h 中的一种类型?

确切的错误:

Shapes.h:20:错误:在 '*' 标记之前需要 ')'
Shapes.h:31:错误:ISO C++ 禁止声明没有类型的“GLWidget”
Shapes.h:31: 错误: 预期 ';'在“*”标记之前
Shapes.h:在成员函数'virtual void Rectangle::draw()'中:
Shapes.h:25:错误:未声明“glWidget”(首先使用此函数)
Shapes.h:25: 错误:(每个未声明的标识符对于它出现的每个函数只报告一次。)

【问题讨论】:

  • 这是特定于 C++ 的,可能不应该标记为 C。
  • shapes 包括 glwidget 和 glwidget 包括形状。对吗?
  • @pmg:如果是,它就不会工作。 Shapes.h 会阻止自己被第二次包含,因此 glwidget.h 中的#include 不会包含任何内容。
  • 是的,它们相互包含。我对每个标题都有宏包含保护,所以它不应该导致无限循环
  • ahhh 好的...那么我如何让 GLWidget 包含在shapes.h 中,以及shapes.h 包含在GLWidget 中呢?

标签: c++ qt


【解决方案1】:

您的头文件之间存在循环依赖关系——Shapes.h 包含 glwidget.h,而 glwidget.h 又包含 Shapes.h。因此,编译器第二次尝试包含 glwidget.h 时,包含保护 AGLWIDGET_H 已被定义,因此它不再包含它,然后 Shapes.h 中的代码尝试使用应该声明但没有声明的类型。

要修复它,您需要删除其中一个依赖项并改用前向声明。由于 glwidget.h 除了声明一个指针成员变量之外实际上并没有使用Shape 类,因此您应该删除它对 Shapes.h 的包含:

glwidget.h:

#ifndef AGLWIDGET_H
#define AGLWIDGET_H

// do NOT include Shapes.h

class Shape;  // forward declaration

class GLWidget : public QGLWidget
{
    ...
    Shape *currentShape;
};

#endif

Shapes.h 和之前一样:

#ifndef SHAPES_H
#define SHAPES_H

#include "glwidget.h"
...
#endif

【讨论】:

  • 这样解决了目前的情况,但是提供的代码并不是一个完整的实现。 GLWidget 将需要知道 Shape 类的方法。一定有某种方法可以让我将它们包含在两者中?
  • hmm 实际上我想只是 glwidget.cpp 需要真正知道 Shape 类的方法,所以我可以在 glwidget.cpp 中包含 Shapes.h?
  • @wallacer:是的,glwidget.cpp 需要包含 Shapes.h,但这没关系,因为它不会创建循环依赖项(因为什么都不包含 glwidget.cpp)。
  • 非常感谢您的帮助,不敢相信这是我第一次遇到这种情况!
  • 我建议将 Shape 类移动到它自己的头文件中(因为实际上,它可能只是一个接口),并将 Shapes.h 重命名为 Rectangle.h。然后,您可以毫无问题地从两个文件中包含 shape.h。
【解决方案2】:

原因是包含顺序 - 您使用循环包含,并且只有包含保护才能阻止您循环编译器。
您可以通过在 glWidget.h 中前向声明形状类并删除 Shapes.h 的包含来解决此问题:

//#include "Shapes.h"
class Shape;

【讨论】:

    猜你喜欢
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多