Imagine the following two classes of a chess game:
TChessBoard = class
private
FBoard : array [1..8, 1..8] of TChessPiece;
...
end;
TChessPiece = class abstract
public
procedure GetMoveTargets (BoardPos : TPoint; Board : TChessBoard; MoveTargetList : TList <TPoint>);
...
end;
I want the two classes to be defined in two separate units ChessBoard.pas and ChessPiece.pas.
How can I avoid the circular unit reference that I run into here (each unit is needed in the other unit's interface section)?
Change the unit that defines TChessPiece to look like the following:
TYPE
tBaseChessBoard = class;
TChessPiece = class
procedure GetMoveTargets (BoardPos : TPoint; Board : TBaseChessBoard; ...
...
end;
then modify the unit that defines TChessBoard to look like the following:
USES
unit_containing_tBaseChessboard;
TYPE
TChessBoard = class(tBaseChessBoard)
private
FBoard : array [1..8, 1..8] of TChessPiece;
...
end;
This allows you to pass concrete instances to the chess piece without having to worry about a circular reference. Since the board uses the Tchesspieces in its private, it really doesn't have to exist prior to the Tchesspiece declaration, just as place holder. Any state variables which the tChessPiece must know about of course should be placed in the tBaseChessBoard, where they will be available to both.