Оператор присваивания с членом ссылочного класса - PullRequest
14 голосов
/ 26 декабря 2011

Пока из моего предыдущего вопроса возникают новые проблемы Перегруженный оператор присваивания вызывает предупреждение о рекурсии , меня законно просили опубликовать это как новое. У меня есть элемент ссылочного класса в моем классе Player, и я хочу реализовать конструктор копирования и оператор присваивания (=) этого класса. Я должен упомянуть, что целью является хорошая работа функции vector.erase, потому что без этого она не работает должным образом, насколько я понимаю. Я использую вектор: vector allPlayers; Члены класса Player:

class Player
{

  private:
  int ID;
  int pMoney;
  int doubleIndicator;
  int squarePosition;
  Bank& bank;
  string pName;
  Square* capturedSquare;
  multimap<string, PropertySquare*> squaresColBought;
  multimap<string, House*> housesColBuilt;

}

Обязательно ли избегать использования ссылки в качестве члена класса, если я хочу реализовать оператор присваивания? Как насчет членов карты? Как мне наконец реализовать оператор присваивания?

Другая проблема, которая крайне важна, о которой я не знаю, это то, что происходит с объектами, указанными членами класса указателей, когда я стираю итератор вектора, который содержит Player. Любая помощь?

Ответы [ 2 ]

14 голосов
/ 26 декабря 2011

C ++ 'ссылка' может быть только инициализирована, но не может быть присвоена:

int value1(1), value2(2);
int& ref1 = value1; // OK
int& ref2; // compile error: reference not initialized
int& ref3=ref1; // OK: ref3 refers to the same variable as ref1
ref1=value2; // equivalent to 'value1=value2'.

Для этого объект , содержащий ссылку, также может быть только инициализирован!

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

Когда вы думаете об этом, имеет смысл:

Ссылочная концепция определяет «псевдоним для другой переменной.Псевдоним подразумевает, что все, что вы делаете со своей ссылкой, вы фактически делаете с указанным местоположением.Когда вы применяете присваивание этому псевдониму, фактически вы присваиваете указанному местоположению.Цель ссылки будет потеряна, если вы сможете указать ее в другом месте с помощью присваивания.

Если последнее - то, что вам нужно, вы должны использовать указатель.

8 голосов
/ 26 декабря 2011

Я бы воздержался от использования ссылочного элемента, когда вам нужен оператор присваивания.Если вместо этого вы используете (умный) указатель, вы можете просто сделать

Player &operator=(Player const &other)
{
    bankPtr = other.bankPtr;
    // copy other members
}

В текущей ситуации bank = other.bank скопирует содержимое other.bank вместо указания this->bank на содержимое, на которое ссылаетсяother.bank.

Что касается multimap -типовых членов, их можно скопировать без проблем, но имейте в виду, что вы получите "глубокую" копию ключей (так как онитипа string), но это "мелкая" копия указателя значений, так что вы в конечном итоге получаете общее состояние.Возможно, вы захотите использовать shared_ptr для значений.

...