我正在尝试制作棋盘游戏,因为每一步都必须有效,所以我正在复制棋盘并采取行动以便我可以验证该移动是否有效。
首先,我将电路板上的所有位置初始化为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;
}
}
}
}
我在董事会的容器是:
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);
编译时没有任何错误或警告。我应该使用哪一个?
答案 0 :(得分:1)
这是浅副本:
board_[p] = gb.board_.at(p);
这是深副本:
board_[p] = new Pieces(*gb.board_.at(p));
第一个只复制指针,因此对board_
中某个部分的更改将导致gb.board_
中同一个部分的更改。第二个实际上是复制数据,因此更改是隔离的。
使用哪个取决于您的应用程序。如果您希望更改传播,则浅拷贝。否则,您需要一份深层副本。
值得注意的是,您的代码段使您看起来面临严重的内存泄漏风险。您正在创建new
件,但绝不会delete
- 。
答案 1 :(得分: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);
答案 2 :(得分:0)
那么,board_ [p]可以是指向Pieces的指针吗?
然后第一个是正确的。第二个是片段ID号(根据我的理解,不是你真正打算指定的指针)。
答案 3 :(得分:0)
由于您不想修改原件,因此需要深层复印。第二个是浅拷贝。所以你需要第一个。
答案 4 :(得分:0)
第一个将进行深拷贝,即复制对象(克隆它们),而第二个将进行浅拷贝,即将指针复制到对象。在后一种情况下,您必须具有对Piece
个对象的相同实例的引用。这样做的问题是,如果其中一块板删除了这些块,另一块将指向悬空记忆。