Оператор присваивания с ссылочным классом

Пока новые проблемы растут из моего предыдущего вопроса Перегруженный оператор присваивания вызывает предупреждение о рекурсии, я был законно призван опубликовать его как новый. У меня есть ссылочный класс в моем классе 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. Любая помощь?

Ответ 1

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

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

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

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

Ответ 2

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

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'.

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

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

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

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

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