0

我正在尝试制作棋盘游戏,因为每一步都必须有效,所以我正在制作棋盘的副本并进行移动,以便我可以验证该移动是否有效。

首先,我将棋盘上的所有位置初始化为 0(遍历棋盘并将每个 p 设置为 0

 pair<int, int> p(y, x); 
 board_[p] = 0;

这是抄板法

void Board::copy(Board & gb) {
for (int y = MIN_Y; y <= MAX_Y; ++y) {
    for (int x = MIN_X; x <= MAX_X; ++x) {
        pair<int, int> p(y, x); 
        if (gb.board_.at(p) != 0) {
            board_[p] = new Pieces(*gb.board_.at(p));  // **where I am confused**
        } else {
            board_[p] = 0;
        }   
    }
}
}

我在 Board 中的容器是:

map<pair<int,int>, Pieces*> board_;

现在在一个游戏方法中,我复制了棋盘

unsigned int play(Board & b){
   b.copy(*this);
}

我的问题:两者

board_[p] = new Pieces(*gb.board_.at(p)); //Pieces is a class I defined

board_[p] = gb.board_.at(p);

编译没有任何错误或警告。我应该使用哪一个?

4

5 回答 5

1

这是一个拷贝:

board_[p] = gb.board_.at(p);

这是一个拷贝:

board_[p] = new Pieces(*gb.board_.at(p));

第一个仅复制一个指针,因此对 in 中的片段的board_更改将导致对 in 中的同一片段的更改gb.board_。第二个实际上是复制数据,因此更改是隔离的。

使用哪个取决于您的应用程序。如果您希望更改传播,那么浅拷贝。否则,您将需要一个深层副本。

值得注意的是,您的代码片段使您看起来面临严重内存泄漏的风险。你正在创作new作品,但从不制作delete它们。

于 2013-02-19T22:39:49.387 回答
1

任何一个都可能是正确的,但您可能想要第一个。第一个将把每一个都复制Pieces到新的板上——这被称为深拷贝。第二个只会复制指向每个指针的指针Pieces,因此两个板都指向同一组Pieces——这是一个浅拷贝。

然而,这里有一个更大的问题。您正在定义一个copy函数,但 C++ 为我们提供了一种语言特性来执行此操作 - 复制构造函数。您应该改为定义一个函数,如下所示:

Board::Board(const Board& other_board) {
  // Copy everything from other_board to this board
}

你会像这样使用它:

Board board;
Board newBoard(b);
于 2013-02-19T22:42:26.777 回答
0

那么, board_[p] 可以是指向 Pieces 的指针吗?

那么第一个是正确的。第二个是零件编号(据我了解,不是您真正打算分配的指针)。

于 2013-02-19T22:37:47.607 回答
0

由于您不想修改原始文件,因此您需要一个深层副本。第二个是浅拷贝。所以你需要第一个。

于 2013-02-19T22:39:57.463 回答
0

第一个将进行深拷贝,即复制对象(克隆它们),而第二个将进行浅拷贝,即复制指向对象的指针。在后一种情况下,您必须使用具有对相同Piece对象实例的引用的板。这样做的问题是,如果其中一个板删除了碎片,另一个将指向悬空内存。

于 2013-02-19T22:42:58.593 回答