Reputation: 135
I am chasing error messages around in circles trying to figure out how I can get what I need working.
I am making a chess game where each chessmen is a class and there is an interface class named Piece.
Piece.h
class Piece {
public:
virtual ~Piece() {};
/*
* Verifies the move on a per-piece basis. If the move is valid, make the changes on the board and return true, false otherwise.
*
* @param b Reference to the board
* @param toLocation Where to move the piece
* @return bool If the move is valid
*/
virtual bool move(Board &b, std::pair<int, int> toLocation) { return false; }
protected:
Piece(GameData::Color _c) { c = _c; }
GameData::Color c;
};
Pawn.h
class Pawn : Piece {
public:
Pawn(GameData::Color _c);
virtual ~Pawn();
bool move(Board &b, std::pair<int, int> toLocation);
};
I cannot get this setup working though.
I get an error:
Pawn::Pawn(GameData::Color _c) : c(_c) {
no matching function for call to Piece::Piece()
I change the visibility of Piece to:
class Pawn : public Piece
But I get loads more errors where I don't have an empty constructor for piece again.
I am setting this up to try and make a 2D array of Pieces to represent the board:
board = new Piece**[SIZE];
for(int i = 0; i < SIZE; ++i)
board[i] = new Piece*[SIZE];
/* Setup initial positions */
board[0][0] = new Rook(GameData::BLACK);
Which is why I cannot make the move method purely virtual.. because the new Piece* call complains that it needs to be implemented.
Upvotes: 2
Views: 821
Reputation: 437684
The compiler is complaining because your Pawn
constructor does not specify how its Piece
base sub-object should be initialized. Normally not specifying this will result in the default constructor of Piece
being called, but Piece
does not have a default constructor, hence the error.
Fix it by being explicit:
Pawn::Pawn(GameData::Color _c) : Piece(_c) {}
This tells the compiler that you want to initialize the base by calling the constructor that accepts a Color
; that constructor will take care of assigning c = _c
so (given the simplified example) you are left with an empty body for Pawn::Pawn
.
Incidentally, since you intend to use Piece
not only as a base class but also to expose an interface to the outside world, Pawn
should derive publicly from Piece
.
Upvotes: 5
Reputation: 4012
You have to call the Piece
constructor via the initialization list:
Pawn(GameData::Color _c): Piece(_c) {}
Or create a default constructor and initialize the values via a method. Your choice.
Upvotes: 5