Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建抽象类的克隆_C++_Pointers_Abstract Class_Chess - Fatal编程技术网

C++ 创建抽象类的克隆

C++ 创建抽象类的克隆,c++,pointers,abstract-class,chess,C++,Pointers,Abstract Class,Chess,我正在编写一个国际象棋程序,我有一个抽象类,名为Pieces。我在我的主类中通过使用指针使用这个抽象类,比如:Pieces*newset=currentboard[] 如果我在这块板上移动的话,实际上就是移动了。我想分析董事会的当前状态,从而创建董事会的副本。我该怎么做 下面给出了我的作品课程的示例以及我正在做的事情 class Piece { public: Piece(char cColor) : mcColor(cColor) {} ~Piece() {} vi

我正在编写一个国际象棋程序,我有一个抽象类,名为
Pieces
。我在我的主类中通过使用指针使用这个抽象类,比如:
Pieces*newset=currentboard[]

如果我在这块板上移动的话,实际上就是移动了。我想分析董事会的当前状态,从而创建董事会的副本。我该怎么做

下面给出了我的
作品
课程的示例以及我正在做的事情

class Piece
{
  public:
    Piece(char cColor) : mcColor(cColor) {}
    ~Piece() {}
    virtual char GetPiece() = 0;
    virtual int GetValue() = 0;
    virtual int GetPieceActionValue() = 0;
    char GetColor() {
        return mcColor;
    }
    bool IsLegalMove(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) {
        Piece* qpDest = NewBoard[DestRow][DestCol];
        if ((qpDest == 0) || (mcColor != qpDest->GetColor())) {
            return LegalSquares(CurrentRow, CurrentCol, DestRow, DestCol, NewBoard);
        }
        return false;
    }

  private:
    virtual bool LegalSquares(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) = 0;
    char mcColor;
};
下面是一个派生类的示例:

class Bishop
{
  public:
    Bishop(char cColor) : Piece(cColor) {}
    ~Bishop() {}

  private:
    virtual char GetPiece() {
        return 'B';
    }
    virtual int GetValue() {
        return 325;
    }
    virtual int GetPieceActionValue() {
        return 3;
    }
    bool LegalSquares(int CurrentRow, int CurrentCol, int DestRow, int DestCol, Piece* NewBoard[8][8]) {
        if ((DestCol - CurrentCol == DestRow - CurrentRow) || (DestCol - CurrentCol == CurrentRow - DestRow)) {
            // Make sure that all invervening squares are empty
            int iRowOffset = (DestRow - CurrentRow > 0) ? 1 : -1;
            int iColOffset = (DestCol - CurrentCol > 0) ? 1 : -1;
            int iCheckRow;
            int iCheckCol;
            for (iCheckRow = CurrentRow + iRowOffset, iCheckCol = CurrentCol + iColOffset;
                iCheckRow !=  DestRow;
                iCheckRow = iCheckRow + iRowOffset, iCheckCol = iCheckCol + iColOffset)
            {
                if (NewBoard[iCheckRow][iCheckCol] != 0) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
};
使用类进行移动:

if (qpCurrPiece->IsLegalMove(StartRow, StartCol, EndRow, EndCol, NewBoard)) {

  // Make the move
  Piece* qpTemp = NewBoard[EndRow][EndCol];
  NewBoard[EndRow][EndCol] = NewBoard[StartRow][StartCol];
  NewBoard[StartRow][StartCol] = 0;

  // Make sure that the current player is not in check
  if (!GameBoard.IsInCheck(mcPlayerTurn)) {
    delete qpTemp;
    bValidMove = true;
  } else { 

    // Undo the last move
    NewBoard[StartRow][StartCol] = NewBoard[EndRow][EndCol];
    NewBoard[EndRow][EndCol] = qpTemp;
  }
}

我希望能够在不使用指针的情况下引用这个类,这样就不会对电路板进行永久性更改

您需要有一个抽象方法

 Piece *Piece::Duplicate()
然后在子类中实现它,即

 class Bishop {
   Bishop(const Bishop &b) { ... } // copy constructor
   Piece *Duplicate() { Bishop *n = new Bishop(*this); // calls copy constructor
     return n; }
 }

您需要为每个类提供一个virtual Clone()函数,对于Bishop,该函数如下所示:

Piece * Bishop :: Clone() {
     return new Bishop( * this );
}
现在要从OldBoard克隆电路板,请执行以下操作:

Board newboard;   // assume board is 8x8 matrix of Piece *

for ( int i = 0; i < 8; i++ ) {
    for ( int j = 0; j < 8; j++ ) {
       newboard[i][j] = OldBoard[i][j]->Clone();
    }
}
Board newboard;//假设电路板是工件的8x8矩阵*
对于(int i=0;i<8;i++){
对于(int j=0;j<8;j++){
newboard[i][j]=OldBoard[i][j]>Clone();
}
}

或者您可以为Bishop类编写一个副本构造函数,然后假设您的currentBoard是Bishop类的实例,则该类将实现一个深度副本。

+1来自我。值得一提的是,在克隆方法上使用协变返回类型可能很有用,即在Bishop中,函数可以返回Bishop*(即,当有Bishop实例时,不必强制转换)。此外,复制构造函数和赋值运算符可能也应该受到保护。很抱歉,我是个扫兴的人,但要玩真正的计算机象棋,你必须每秒执行数百万次。在动态内存中克隆片段并不实用,除非作为练习。也许你应该看看这里?