2013-02-19 52 views
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; 
     } 
    } 
} 
} 

我集裝箱板是:

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); 

編譯沒有任何錯誤或警告。我應該使用哪一個?

回答

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); 
+0

其實我有:Board :: Board(board& } – HoKy22 2013-02-19 22:52:58

+0

它本質上是一個拷貝構造函數嗎? – HoKy22 2013-02-19 22:53:20

+0

@ HoKy22它應該把'const Board&'作爲一個拷貝構造函數。 – 2013-02-19 23:05:24

0

那麼,board_ [p]可以是指向Pieces的指針?

然後第一個是正確的。第二個是件ID號碼(不是我真正打算分配的指針,根據我的理解)。

1

這是一個副本:

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

這是一個副本:

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

第一個唯一拷貝的指針,所以改變到一塊在board_將導致gb.board_中的相同作品發生更改。第二個實際上覆制數據,所以更改是孤立的。

要使用哪個取決於您的應用程序。如果你想要更改傳播,那麼淺拷貝。否則,您需要深層複製。

值得注意的是,您的代碼片段使您看起來像是處於嚴重內存泄漏的風險之中。您正在創建new件,但從來沒有delete-它們。

0

由於您不想修改原件,因此需要進行深層複印。第二個是淺拷貝。所以你需要第一個。

0

首先會做一個深拷貝,即複製對象(克隆它們),而第二會做一個淺拷貝,即將指針複製到對象。在後一種情況下,您必須在板上引用Piece對象的相同實例。問題在於如果其中一塊板子刪除了這些棋子,另一塊會指向懸停的記憶。 (gb);