【问题标题】:C++ - Swap function of custom types not workingC++ - 自定义类型的交换功能不起作用
【发布时间】:2013-03-18 17:46:44
【问题描述】:

我目前正在用 C++ 编写 n-puzzle,尽管由于某种原因我无法交换棋盘的元素。让我解释。我有一个“Piece”类(该类的一些方法):

Piece::Piece(int l, int c, int n):
line(l), 
column(c), 
number(n)
{

}

int Piece::getLine()
{
  return line;
}

int Piece::getColumn() const
{
  return column;
}

int Piece::getNumber() const
{
  return number;
}

void Piece::setLine(const int new_line)
{
  this -> line = new_line;
}

void Piece::setColumn(const int new_column)
{
  this -> column = new_column;
}

void Piece::setNumber(const int new_number)
{
  this -> number = new_number;
}

我还有一个执行游戏的 Board 类。 Board 是“Piece”类型向量的向量。正在使用以下代码创建板:

for(size_t i = 0; i < this -> width; i++)
  {
    vector<Piece> row;

    for(size_t j = 0; j < this -> height; j++)
    {
      row.push_back(Piece(i, j, ((j == this -> width - 1) && (i == this -> height - 1) ? 0 : i * this -> width + j + 1)));
    }  
    board.push_back(row);
  }

到这里为止都没有问题。问题是当我想交换 Board 的两个元素时。想象一下,我们有一个 3x3 游戏。如果我运行以下代码,结果将是错误的

swapPieces(board[0][0], board[1][0]);
swapPieces(board[1][0], board[2][0]);
cout << board[0][0] << "\t" << board[0][0].getLine() << endl;

谜题是正确的:

4 2 3

7 5 6

1 8 0

但是通过执行 board[0][0].getLine() 输出为 1,即 Piece 的初始位置!我真的不知道我做错了什么。如果有人能帮帮我,我将不胜感激:)

编辑:已添加交换件:

void Board::swapPieces(Piece &p1, Piece &p2)
{
  Piece p = p1;
  p1 = p2;
  p2 = p;
}

【问题讨论】:

  • 至少,我们需要看到更多代码来显示board 的确切声明和定义,当然还有swapPieces
  • 问题是你没有给我们swapPieces函数的代码,而你知道问题出在这个函数上......
  • Stephane Rolland:我添加了swapPieces,这是我的错误!对不起。

标签: c++ class function swap


【解决方案1】:

代码库确实有两种方式来表示 Piece 位置。一个是 Piece 对象中的“line”和“column”变量,另一个是 board 和 Vector 行容器中 Piece 对象的排序。编程的一个基本原则是 DRY(不要重复自己)。就像您现在遇到的那样,它会导致错误。 swapPieces 可能正在交换容器内的对象,但不更新对象变量。您可以通过使两种表示一致(设置行和列变量)在 swapPieces 代码中修补此问题,但从长远来看,确定两者中的哪一个是多余的会更清晰。

【讨论】:

  • 或者像这样改变swapPiecesint n = p1.number; p1.number = p2.number; p2.number = n;
  • 您建议的代码将在短期内有效,但如果将其他成员变量添加到 Piece,您必须记住再次访问 swapPieces 代码。如果变量是受保护的或私有的,那么您需要做更多的工作。此外,可能会保留指向游戏片段的指针的代码库的其他部分可能会受到影响。
  • 那么,交换棋盘中的两块的最佳解决方案是什么?我现在尝试在不同的部分中使用 setLine() 和 setColumn() 并且它有效,但代码似乎不可读。虽然,我接受你的回答:)
  • 到目前为止,仅基于对代码的一瞥,我将不理会 swapPieces,然后删除 Piece 中的行和列变量,并让您的 Board 类负责跟踪哪一行和哪一列给定 Piece 在 - 例如可能是 Board::whereIs( Piece*, int& row, int& col) 函数。一个愚蠢但简单的搜索(例如,通过每一行的 stl::find)将识别 Piece 的行和列。如果以后这成为性能瓶颈,您可以重新设计 Board 如何存储和搜索 Pieces 的内部结构,而不会影响 Board 外部的代码如何访问 Piece 对象。
【解决方案2】:

首先确保您的副本 c'tor 实际被调用(我还没有看到实现)。 其次,确保当您使用 board[0][0] 时,您使用的是实际的 Object 而不是它的副本

【讨论】:

    【解决方案3】:

    swapPieces 似乎可以工作,但除非您同时调用 setLinesetColumn,否则这些碎片不会知道它们已被移动。现在,这些片段将包含它们在构造函数中设置的原始位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 2012-09-10
      • 2016-11-24
      • 1970-01-01
      • 2016-02-05
      相关资源
      最近更新 更多