制作一块板子

时间:2013-02-19 22:31:36

标签: c++ pointers memory-management copy

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

首先,我将电路板上的所有位置初始化为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);

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

5 个答案:

答案 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个对象的相同实例的引用。这样做的问题是,如果其中一块板删除了这些块,另一块将指向悬空记忆。