Я пытаюсь сделать игру в шахматы. Я сделал два заголовочных файла и их файлы cpp: Pieces.h и ChessBoard.h. Я включил Pieces.h в ChessBoard.h, и он прекрасно компилируется. Но я хочу иметь метод в Pieces, который требует ChessBoard в качестве параметра. Поэтому, когда я пытаюсь включить ChessBoard.h в Pieces.h, я получаю все странные ошибки. Может кто-нибудь подсказать, как включить ChessBoard.h в Pieces.h?
Pieces.h:
#ifndef PIECES_H
#define PIECES_H
#include <string>
#include "ChessBoard.h"using namespace std;
class Pieces{
protected:
bool IsWhite;
string name;
public:
Pieces();
~Pieces();
// needs to be overwritten by every sub-class
virtual bool isValidMove(string initial,string final, ChessBoard& chessBoard) = 0;
bool isWhite();
void setIsWhite(bool IsWhite);
string getName();
};
#endif
ChessBoard.h:
#ifndef CHESSBOARD_H
#define CHESSBOARD_H
#include "Pieces.h"#include <map>
#include <string.h>
class ChessBoard
{
// board is a pointer to a 2 dimensional array representing board.
// board[rank][file]
// file : 0 b 7 (a b h)
std::map<std::string,Pieces*> board;
std::map<std::string,Pieces*>::iterator boardIterator;
public:
ChessBoard();
~ChessBoard();
void resetBoard();
void submitMove(const char* fromSquare, const char* toSquare);
Pieces *getPiece(string fromSquare);
void checkValidColor(Pieces* tempPiece); // to check if the right player is making the move
};
#endif
ошибки:
ChessBoard.h:26: error: ‘Pieces’ was not declared in this scope
ChessBoard.h:26: error: template argument 2 is invalid
ChessBoard.h:26: error: template argument 4 is invalid
ChessBoard.h:27: error: expected ‘;’ before ‘boardIterator’
ChessBoard.h:54: error: ISO C++ forbids declaration of ‘Pieces’ with no type
ChessBoard.h:54: error: expected ‘;’ before ‘*’ token
ChessBoard.h:55: error: ‘Pieces’ has not been declared
Это связано с тем, что называется круговой зависимостью. круговая зависимость
проблема в том, что когда ваша программа начинает компилироваться (предположим, что chessboard.h начнет компиляцию первой).
Он видит директиву для включения кусков .h, поэтому пропускает оставшуюся часть кода и перемещается в куски.
Здесь компилятор видит директиву для включения chessboard.h
но так как вы включили защиту заголовка, она не включает chessboard.h во второй раз.
Он продолжает компилировать остальную часть кода в куски.
Это означает, что класс в chessboard.h еще не объявлен, и это вызывает ошибку
Лучшая идея, чтобы избежать этого, состоит в том, чтобы заранее объявить другой класс, а не включать заголовочный файл. Но вы должны заметить, что вы не можете создавать какие-либо объекты класса, объявленного вперед, вы можете сделать только указатель или ссылочную переменную.
Объявление вперед означает объявление класса перед его использованием.
class ChessBoard;
class Pieces
{
ChessBoard *obj; // pointer object
ChessBoard &chessBoard;
Это называется избыточным включением.
Когда вы включаете H в оба класса (Pieces и Chessboards), C ++ обычно выдает странные ошибки. Это очень распространенная ошибка, когда вы начинаете программировать на C ++.
Сначала я предлагаю вам проверить, действительно ли вам нужно, чтобы каждый класс был включен в другой. Если вы действительно уверены в этом, то способ исправить это — выбрать один из них и переместить include в cpp.
Затем добавьте предварительное объявление класса в h.
Например, если вы выбираете ChessBoard для изменения:
#include <map>
#include <string.h>
class Pieces;
class ChessBoard
{
В css ChessBoard у вас будет #include «Pieces.h»
Части h и cpp остаются прежними.