3

我有三个 (C++) 类:Player、Hand 和 Card。

玩家有一个成员hand,它握着一只手。它还有一个方法 getHand(),它返回手的内容。

Hand Player::getHand() {
    return hand;
}

Hand 有一个方法 addCard(Card c),它可以向手牌添加一张牌。

我想做这个:

player1.getHand().addCard(c);

但它不起作用。它不会抛出错误,所以它正在做某事。但是如果我之后检查player1手上的内容,那张牌并没有被添加。

我怎样才能让它工作?

4

8 回答 8

2

如果 getHand() 按值返回,则您正在修改手的副本而不是原始手。

于 2008-09-22T03:27:41.320 回答
1

如果 getHand() 没有返回引用,您将遇到麻烦。

于 2008-09-22T03:28:30.693 回答
1

Player.addCardToHand() 方法不是不合理的,如果您没有理由以其他方式暴露手。这在某些方面可能是理想的,因为您仍然可以提供手牌的副本以进行获胜检查比较,并且没有人可以修改它们。

于 2008-09-22T03:37:08.053 回答
1

您的方法需要返回一个指针或对玩家的 Hand 对象的引用。然后您可以将其称为“player1.getHand()->addCard(c)”。请注意,这是您使用的语法,它是一个指针。

于 2008-09-22T03:39:34.833 回答
1

返回对手对象的引用,例如。

Hand &Player::getHand() {
    return hand;
}

现在您的 addCard() 函数正在正确的对象上运行。

于 2008-09-22T03:42:05.577 回答
0

getHand() 的声明是什么?它是返回一个新的 Hand 值,还是返回一个 Hand& 引用?

于 2008-09-22T03:28:28.103 回答
0

如前所述,您可能正在修改副本而不是原件。

为了防止这种错误,您可以将复制构造函数和等于运算符显式声明为私有。

  private:
    Hand(const Hand& rhs);
    Hand& operator=(const Hand& rhs);
于 2008-09-22T03:33:50.617 回答
0

getX() 通常是成员 x 的访问器函数的名称,类似于您自己的用法。然而,“getX”访问器也经常是一个只读函数,因此在代码库的其他情况下看到修改 X 的“getX”调用可能会令人惊讶。

所以我建议,而不是仅仅使用一个引用作为返回值,来实际修改一下代码设计。一些替代方案:

  • 公开一个返回指针(或引用)的getMutableHand方法。通过返回一个指针,您强烈建议调用者使用指针表示法,这样任何阅读代码的人都会看到这个变量正在改变值,并且不是只读的。
  • 使Player 成为 Hand 的子类,以便任何操作 Hand 的东西也可以直接在 Player 上工作。直观地说,您可以说 Player 不是 Hand,但从功能上讲,它们具有正确的关系 - 每个 Player 都只有一只手,而且您似乎确实希望能够通过 Player 获得与 Hand 相同的访问权限会直接。
  • 直接为您的 Player 类实现addCard方法。
于 2008-09-22T04:02:12.937 回答