Qt ISO C ++ запрещает объявление без типа - заголовочный файл включен? - PullRequest
1 голос
/ 29 сентября 2010

Я получаю объявление о запрещении без ошибки типа в приложении 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

Я не понимаю, почему я не могу использовать свой GLWidget в Shapes.h,Ошибка в Shapes.h на линии, где я объявляю GLWidget * glWidget;Если я использую предварительную декларацию т.е.класс GLWidget;эта ошибка исчезает, но тогда я не могу использовать методы GLWidget, как в Rectangle.draw ()

У кого-нибудь есть идея, почему компилятор не будет видеть 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: ошибка: (Каждый необъявленный идентификатор сообщается только один раз для каждой функции, в которой он появляется.)

Ответы [ 2 ]

7 голосов
/ 29 сентября 2010

У вас есть круговая зависимость между вашими заголовочными файлами - Shapes.h включает glwidget.h, который снова включает Shapes.h. Итак, во второй раз, когда компилятор пытается включить glwidget.h, include guard 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
1 голос
/ 29 сентября 2010

Причиной является порядок включения - вы используете циклическое включение, и только защита включения не позволяет вам зациклить компилятор.
Вы можете решить эту проблему в вашем конкретном случае, объявив класс shape в glWidget.h и удалив включение для Shapes.h:

//#include "Shapes.h"
class Shape;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...