noctilux
noctilux

Reputation: 803

Incomplete type error header -- how to fix?

I thought I had a handle on how to fix circular dependencies, but I just can't fix the following, so I'd be grateful for any help!

I am writing a chess program and I have a class Pieces.

It's in file Pieces.cpp and includes Pieces.h.

Pieces.h include Rook.h.

Rook.h include ChessPiece.h

ChessPiece.h include ChessBoard.h.

Now,

ChessBoard.h include Pieces.h.

I have include guards everywhere, so it goes all right; except ChessBoard actually owns Pieces rather than just having Pointers/References to them:

private:
    Pieces black_pieces;
    Pieces white_pieces;

I did a forward declaration of Pieces, but the compiler complains about an incomplete type on this line. I can see why: at this point, the compiler does not know how much space to allocate for a class of type Pieces, though it knows one exists from my forward declaration.

My problem is that I want ChessBoard to store these Pieces objects, so I cannot simply have pointers to them. I suppose I could put them on the heap, but I've heard that using the heap is generally discouraged. Is this a case where maybe it would be useful, or is there a solution I am overlooking?

I hope my explanation is understandable even without posting the code -- there would be a lot of it!

Thanks for your help.

Upvotes: 0

Views: 432

Answers (1)

Thomas Matthews
Thomas Matthews

Reputation: 57678

Forward declarations work for member references and pointers. When declaring instances of classes or structures in another class / structure, you need the full declaration.

Your question sounds like you have an issue with your design / architecture.
A Rook is-a Chess_Piece. Fine, sounds good.

The class Pieces sounds ambiguous.
Do you need a specialized type for containing pieces or can you use std::vector<Chess_Piece*>?

A Chessboard should contain zero or more instances of Chess_Piece. A common implementation is a 2d array of pointers to Chess_Piece. The pointers help support polymorhphism.

Another implementation could be a vector of . This is of the view that a chess board has pieces at different locations on the board.

Edit 1: Allocation of pieces
I suggest having a factory which returns pointers to the pieces. Since the quantity of pieces is known and won't change, they can be allocated as static, automatic variables.

class Piece_Factory
{
  static std::vector<Pawn> white_pawns;
  static std::vector<Pawn> black_pawns;
  static Queen             white_queen(white);
  static Queen             black_queen(black);
public:
  Piece_Factory()
  {
    Pawn wp(white);
    Pawn bp(black);
    for (unsigned int i = 0; i < 8; ++i)
    {
      white_pawns.push_back(wp);  // Append a copy to the vector.
      black_pawns.push_back(bp);
    }
  }
  Chess_Piece * get_white_pawn(unsigned int index)
  {
    return &white_pawn[index];
  }
  Chess_Piece * get_white_queen(void)
  {
    return &white_queeen;
  }
};

Upvotes: 1

Related Questions