2014-12-28 70 views
0

我讀了很多關於純虛擬呼叫的錯誤,但我也沒弄明白什麼是錯我的代碼:訪問分段故障到現場使用純虛擬函數

我編程,國際象棋遊戲,使用多態。

這裏的一些代碼:

Piece.hpp(母公司爲所有的遊戲作品)

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(例如)

#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; 
}; 

和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() { 
    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'); 
} 

局::打印

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.. 
     } 
    } 
} 

卻困在該行:

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

我得到:

純虛方法稱爲

我沒有叫構造函數和析構函數

中的函數把virtual關鍵字上述~Piece()析構函數後,這個問題解決了。但是,現在在同一行,我得到

信號:SIGSEGV(分段故障)

什麼想法?

這裏多一些信息:

我宣佈董事會內部象棋的主。cpp:

Board boardGame;

然後我送爲void瑣事(板棋盤遊戲)是這樣的:

瑣事(棋盤遊戲);

和內部我送爲void getNextMove(局板,串whitePlayer,串blackPlayer)所示:

getNextMove(棋盤遊戲,whitePlayer,blackPlayer);

,然後我使用:

boardGame.print();

+0

TL; DR;創建抽象類'virtual'的析構函數:'virtual〜Piece(){}'。 –

+0

@πάνταῥεῖ謝謝!現在我得到Signal:SIGSEGV(Segmentation fault)。任何想法? –

+0

@AviadLevy越界訪問(看起來可能)? –

回答

2

我假設你有Board類型的對象,你做它的副本,但你沒有拷貝構造函數,並且我也認爲Board::board是動態分配的。

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

你需要遵守三個原則,並提供爲Board拷貝構造函數,賦值操作符和析構函數有效實現。

或者您可以將Board::board聲明爲指針的向量而不用擔心內存管理。

這是基於一個假設,如果你已經這樣做,那麼這個答案不適用。

+0

謝謝!只是爲了確保我明白了: 我需要構建複製構造函數到Board,因爲當我將它從函數發送到函數時,其數據會丟失 –

+0

@AviadLevy好...不是真的 - 請閱讀鏈接答案以瞭解詳細信息。當你傳值時,你做一個淺拷貝,當函數退出時,拷貝被刪除,如果成員有一個析構函數,它將刪除它。 –

+0

謝謝!我認爲理解! 會嘗試,並在稍後報告。 –