2010-09-28 78 views
1

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

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方法

任何人都有一个想法,为什么编译器在Shapes.h中看不到GLWidget类型?

精确错误:

Shapes.h:20:错误:预期 ')' 前 '*' 标记
Shapes.h:31:错误:ISO C++禁止 'GLWidget' 的声明无类型
Shapes.h:31:error:expected';'在'*'标记之前
Shapes.h:在成员函数virtual void Rectangle :: draw()中:
Shapes.h:25:错误:'glWidget'未声明(首次使用此函数)
Shapes.h :25:错误:(每个未声明的标识符仅对其出现的每个函数报告一次)。

+0

这是C++特异性的,并且可能不应该被标记C. – nategoose 2010-09-28 21:36:35

+3

形状包括glwidget和glwidget包括形状。那是对的吗? – pmg 2010-09-28 21:37:32

+0

@pmg:如果是,它将不起作用。 Shapes.h防止自己再次被包含,因此glwidget.h中的#include将不包含任何内容。 – cHao 2010-09-28 21:41:23

回答

7

你有你的头文件之间的循环依赖 - 形状。 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 
+0

坚实的解释,+1。 – 2010-09-28 21:44:24

+0

这解决了目前的情况,但提供的代码并不是一个完整的实现。 GLWidget需要知道Shape类的方法。我必须有办法让他们都包括在内? – wallacer 2010-09-28 21:48:06

+0

嗯其实我想只是glwidget.cpp需要实际知道形状类的方法,所以我可以在glwidget.cpp中包含Shapes.h? – wallacer 2010-09-28 21:50:19

1

原因是包含顺序 - 您使用循环包含,并且只有包含守护程序阻止您循环编译器。
您可以通过前置声明中glWidget.h形状类和去除包括Shapes.h你的具体情况解决此问题:

//#include "Shapes.h" 
class Shape; 
相关问题