4

I'm getting the error "expected class-name before '{' token" in my C++ Qt project. After googling it, it seems like its a problem of circular includes. I have pawn.h that includes piece.h, which includes board.h, which completes the circle by including pawn.h. I've read that this can be fixed with forward declarations, but I've tried forward declaring a few of problem classes, and it doesn't work.

#ifndef PAWN_H
#define PAWN_H

#include "piece.h"

class Pawn : public Piece
{
    Q_OBJECT
public:
    explicit Pawn(QWidget *parent = 0);
};

#endif // PAWN_H

.

#ifndef PIECE_H
#define PIECE_H

#include <QWidget>
#include "board.h"

class Board;
class Piece : public QWidget
{
    Q_OBJECT
public:
    explicit Piece(QWidget *parent = 0);
    void setPosition(int rank, int file);
    QPixmap pixmap;

protected:
    void paintEvent(QPaintEvent *);

private:
    int rank;
    int file;
    int x;
    int y;
};

#endif // PIECE_H

.

#ifndef BOARD_H
#define BOARD_H

#include <QWidget>
#include <QVector>
#include <QGridLayout>
#include "square.h"
#include "pawn.h"
#include "knight.h"
#include "bishop.h"
#include "queen.h"
#include "king.h"

class Board : public QWidget
{
public:
    explicit Board(QWidget *parent = 0);
    QVector < QVector<Square *> > sqrVector;
    Pawn *pawn[8];

    Knight *knight[2];

    Bishop *bishop[2];

    Queen *queen;
    King *king;

private:
    QGridLayout *layout;
};

#endif // BOARD_H
gsgx
  • 12,020
  • 25
  • 98
  • 149

2 Answers2

4

Instead of randomly trying things, try changing board.h to include forward declarations for all the pieces:

board.h

class Pawn;
class Knight;
class Bishop;
class Queen;
class King;

And remove the corresponding #include statements. (You'll probably need to put those #include statements in board.cpp, when you decide you need to see inside the various piece classes.)

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • The problem was fixed by a comment on the question. But I did what you said as well and got the following error. Invalid use of the incomplete type 'struct Pawn' - main.cpp 9 Forward declaration of 'struct Pawn' - board.h 14 Do you know why that happens? Also, is it general practice to use forward declarations instead of includes when you're including specific things like classes? – gsgx Aug 26 '11 at 03:55
  • 5
    Yes, you'll need to `#include "pawn.h"` into any *`.cpp`* files (such as `main.cpp`) that use the internals of `Pawn`. Doing this is generally good practice because it speeds up your compile times (for large projects). – Greg Hewgill Aug 26 '11 at 03:57
  • Including "pawn.h" into board.cpp and main.cpp did the trick. But when I instead put class Pawn; in those spots instead of the include, then the error stayed. I would much rather use class Pawn; if possible, but why does it give that error while #include works? – gsgx Aug 26 '11 at 04:04
  • 1
    @gsingh2011, by including the header, your providing the definition. Only including the statement `class Pawn;` does not provide the rest of the definition needed by the cpp files that use it. The reason board.h doesn't need anything more is that it doesn't reference any of the class methods, so the forward declaration is sufficient. main.cpp and board.cpp are likely to use the methods. – rcollyer Aug 26 '11 at 04:17
  • I understand it now, this helped: http://stackoverflow.com/questions/3632818/forward-declaration-vs-include – gsgx Aug 26 '11 at 04:19
1

Your main problem lays in the file: piece.h. Since board is not referenced explicitly in the file whatsoever, the include for it and the forward declaration should be removed. That will break the circle. Additionally, as Greg pointed out, only forward declarations are needed in board.h.

Community
  • 1
  • 1
rcollyer
  • 10,475
  • 4
  • 48
  • 75