0

I read a lot about the error with pure virtual call, but i didn't figure out what's wrong with my code:

I programmed Chess game, using polymorphism.

here some code:

Piece.hpp (the Parent for all game pieces)

class Piece
{
private:
    char _player;
    virtual int isMoveLegalForSpecificPiece(int positionRow, int positionCol, int targetRow,
                                            int targetCol, Piece *board[8][8]) = 0;
public:
    ~Piece()
    {
    }
    Piece(char player);
    virtual int isMoveLegal(int positionRow, int positionCol, int targetRow, int targetCol,
                            Piece *board[8][8]);
    char getPlayer();
    virtual char getSign() const = 0;
    virtual std::string getUnicodeSymbol() const = 0;
};

Rook.hpp (for example)

#include "Piece.hpp"

class Rook : public virtual Piece {
private:
    std::string _unicode = "265C";
    virtual int isMoveLegalForSpecificPiece(int positionRow, int positionCol, int targetRow,
                                            int targetCol, Piece *board[8][8]);
public:
    Rook(char player) : Piece(player){}
    ~Rook() {}
    virtual std::string getUnicodeSymbol() const;
    char getSign() const;
};

and Rook.cpp

#include "Rook.hpp"
char Rook::getSign() const {return 'r';}
int Rook::isMoveLegalForSpecificPiece(int positionRow, int positionCol, int targetRow,
                                      int targetCol, Piece *board[8][8]) {
    if (positionRow == targetRow) {
        int rightOrLeft = (targetCol - positionCol > 0) ? 1 : -1;
        for (int i = positionCol + rightOrLeft; i != targetCol; i += rightOrLeft) {
            if (board[positionRow][i] != 0) {return 0;  }
        }
        return 1;
    }
    else if (positionCol == targetCol)  {
        int upOrDown = (targetRow - positionRow > 0) ? 1 : -1;
        for (int i = positionRow + upOrDown; i != targetRow; i += upOrDown) {
            if (board[i][positionCol] != 0) {return 0;}
        }
        return 1;
    }
    return 0;
}
std::string Rook::getUnicodeSymbol() const {return _unicode;}

Board::Board()

Board::Board()  {
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            board[i][j] = 0;
        }
    }
    for (int i = 0; i < 8; i++) {
        board[1][i] = new Pawn('w');
        board[6][i] = new Pawn('b');
    }   
    board[7][0] = new Rook('b');
    board[0][0] = new Rook('w');
    board[7][1] = new Knight('b');
    board[0][1] = new Knight('w');
    board[7][2] = new Bishop('b');
    board[0][2] = new Bishop('w');
    board[7][3] = new King('b');
    board[0][3] = new King('w');
    board[7][4] = new Queen('b');
    board[0][4] = new Queen('w');
    board[7][5] = new Bishop('b');
    board[0][5] = new Bishop('w');
    board[7][6] = new Knight('b');
    board[0][6] = new Knight('w');
    board[7][7] = new Rook('b');
    board[0][7] = new Rook('w');
}

Board::print

void Board::print() {
    printRowLetters();
    for (int i = 7; i >= 0; i--){
        cout << (char) ('1' + i) << " ";
        for (int j = 7; j >= 0; j--) {
            string isColor = "0";
            string pieceUnicode = " ";
            if (board[i][j])    {
                isColor = (board[i][j]->getPlayer() == 'w') ? "37" : "30";
                pieceUnicode = board[i][j]->getUnicodeSymbol();
            }
        //some more code..
        }
    }
}

i'm stuck in that line:

pieceUnicode = board[i][j]->getUnicodeSymbol();

i get:

pure virtual method called

i didn't call the function within constructor or destructor

After putting the virtual keyword to the above ~Piece() destructor, this problem was solved. But now on same line i get

Signal: SIGSEGV (Segmentation fault)

any ideas?

here some more info:

i declare board inside main of chess.cpp:

Board boardGame;

then i send to void playGame(Board boardGame) like this:

playGame(boardGame);

and inside i send to void getNextMove(Board board, string whitePlayer, string blackPlayer) like this:

getNextMove(boardGame, whitePlayer, blackPlayer);

and then i'm using:

boardGame.print();

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190

1 Answers1

2

I assume you have an object of type Board and you make copies of it, yet you don't have a copy constructor, and I also assume Board::board is dynamically allocated.

This will cause problems with copying, assignment or destroying. (Read me)

You need to obey the rule of three and provide valid implementations for the copy constructor, assignment operator and destructor of Board.

Or you could declared Board::board as a vector of pointers and not worry about the memory management.

This is all based on an assumption, if you already do this then this answer doesn't apply.

Community
  • 1
  • 1
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • thanks! just to make sure i understood: i need to build copy constructor to Board, because when i send him from function to function, the data its hold is lost – Aviad Levy Dec 28 '14 at 13:36
  • @AviadLevy well... not really - read the linked answer for details. When you pass by value, you make a shallow copy, and when the function exits, the copy is deleted, which deletes the members if it has a destructor. – Luchian Grigore Dec 28 '14 at 13:39
  • thanks! i think understood! will try, and report later. – Aviad Levy Dec 28 '14 at 13:41
  • that was the problem! thanks for helping – Aviad Levy Dec 28 '14 at 14:08