Я думал, что у меня есть способ установить круговые зависимости, но я просто не могу исправить следующее, поэтому я был бы благодарен за любую помощь!
Я пишу шахматную программу, и у меня есть классные Pieces
.
Он в файле Pieces.cpp и включает Pieces.h.
Pieces.h включает Rook.h.
Rook.h включает ChessPiece.h
ChessPiece.h включает ChessBoard.h.
Теперь,
ChessBoard.h включает Pieces.h.
У меня есть везде охранники, так что все в порядке; кроме ChessBoard
фактически владеет Pieces, а не просто указателями/ссылками на них:
private:
Pieces black_pieces;
Pieces white_pieces;
Я сделал предварительную декларацию Pieces
, но компилятор жалуется на неполный тип в этой строке. Я могу понять, почему: на данный момент компилятор не знает, сколько места выделяется для класса типа Pieces
, хотя он знает, что он существует из моего прямого объявления.
Моя проблема в том, что я хочу, чтобы ChessBoard
хранили эти объекты Pieces
, поэтому я не могу просто иметь указатели на них. Полагаю, я мог бы положить их в кучу, но я слышал, что использование кучи обычно обескуражено. Это случай, когда, возможно, это было бы полезно, или есть решение, которое я пропускаю?
Надеюсь, мои объяснения понятны даже без публикации кода - их было бы много!
Спасибо за вашу помощь.
Передовые декларации работают для ссылок и указателей участников. При объявлении экземпляров классов или структур в другом классе/структуре требуется полная декларация.
Ваш вопрос звучит так, как будто у вас проблема с дизайном/архитектурой. Rook
- это Chess_Piece
. Отлично, звучит хорошо.
Класс Pieces
звучит неоднозначно.
Вам нужен специализированный тип для размещения частей или вы можете использовать std::vector<Chess_Piece*>
?
Chessboard
должна содержать ноль или более экземпляров Chess_Piece
. Общая реализация - это 2d массив указателей на Chess_Piece
. Указатели помогают поддерживать полиморфизм.
Другой реализацией может быть вектор. Это означает, что шахматная доска имеет куски в разных местах на доске.
Изменить 1: Распределение частей
Я предлагаю иметь фабрику, которая возвращает указатели на части. Поскольку количество кусков известно и не изменится, их можно выделить как статические, автоматические переменные.
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;
}
};
Chess_Piece
?
Pieces
заранее, правильно. Но вы можете просто сделать это, не так ли?Pieces
включает в себя еще один заголовок, который включаетChessBoard
. Поэтому, когда он выполняет свои директивы препроцессора, он всегда ставитChessBoard
впередиPieces
...