Как использовать метод одного объекта для обновления атрибута другого объекта? - PullRequest
3 голосов
/ 22 сентября 2008

У меня есть три (C ++) класса: Player, Hand и Card.

У игрока есть член, рука, которая держит руку. У него также есть метод getHand (), который возвращает содержимое hand.

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

В руке есть метод addCard (Card c), который добавляет карту в руку.

Я хочу сделать это:

player1.getHand () addCard (с);.

но это не работает. Он не выдает ошибку, поэтому он что-то делает. Но если после этого я проверю содержимое руки player1, карта не будет добавлена.

Как мне заставить это работать?

Ответы [ 8 ]

2 голосов
/ 22 сентября 2008

Если getHand () возвращает по значению, вы изменяете копию руки, а не оригинал.

1 голос
/ 22 сентября 2008

Возвращает ссылку на объект руки, например.

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

Теперь ваша функция addCard () работает с правильным объектом.

1 голос
/ 22 сентября 2008

Ваш метод должен возвращать указатель или ссылку на объект руки игрока. Затем вы можете назвать его как «player1.getHand () -> addCard (c)». Обратите внимание, что это тот синтаксис, который вы бы использовали, это был указатель.

1 голос
/ 22 сентября 2008

Метод Player.addCardToHand () не является необоснованным, если у вас нет оснований иначе выставлять руку. Возможно, это в некотором смысле идеально, так как вы все равно можете предоставить копии раздачи для сравнительных проверок, и никто не может их изменить.

1 голос
/ 22 сентября 2008

Если getHand () не возвращает ссылку, у вас будут проблемы.

0 голосов
/ 22 сентября 2008

getX () часто является именем функции доступа для члена x, аналогично вашему собственному использованию. Однако метод доступа «getX» также очень часто является функцией только для чтения, поэтому в других ситуациях вашей кодовой базы может быть удивительным увидеть вызов «getX», который изменяет X.

Так что я бы предложил вместо того, чтобы просто использовать ссылку в качестве возвращаемого значения, на самом деле немного изменить дизайн кода. Некоторые альтернативы:

  • Предоставить метод getMutableHand , который возвращает указатель (или ссылку). Возвращая указатель, вы настоятельно рекомендуете вызывающей стороне использовать запись указателя, чтобы любой, кто читает код, увидел, что эта переменная изменяет значения и не доступна только для чтения.
  • Сделать Игроком подкласс Руки , так что все, что манипулирует Рукой, также работает непосредственно на Игроке. Интуитивно вы можете сказать, что игрок - это не рука, но функционально у них правильные отношения - у каждого игрока ровно одна рука, и кажется, что вы хотите иметь такой же доступ к руке через игрока, как вы будет напрямую.
  • Непосредственно реализовать метод addCard для вашего класса Player.
0 голосов
/ 22 сентября 2008

Как уже было сказано, вы, вероятно, изменяете копию вместо оригинала.

Чтобы предотвратить ошибку такого рода, вы можете явно объявить конструкторы копирования и операторы равенства как частные.

  private:
    Hand(const Hand& rhs);
    Hand& operator=(const Hand& rhs);
0 голосов
/ 22 сентября 2008

Что такое объявление getHand ()? Возвращает ли оно новое значение Хэнда, или оно возвращает Хэнд и ссылку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...