Оператор присваивания с ссылочным классом
Пока новые проблемы растут из моего предыдущего вопроса Перегруженный оператор присваивания вызывает предупреждение о рекурсии, я был законно призван опубликовать его как новый. У меня есть ссылочный класс в моем классе 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'.
Для этого объект, содержащий ссылку, может быть инициализирован тоже!
И действительно: если вам нужно назначить класс, этот класс не может иметь ссылочные переменные-члены. (по сути, он мог, но присваивание не может заставить этих членов ссылаться на другое место)
Когда вы думаете об этом, это имеет смысл:
Эталонная концепция определяет "псевдоним" для другой переменной. Наложение псевдонимов подразумевает, что все, что вы делаете с вашей ссылкой, вы фактически делаете в ссылочном местоположении. Когда вы применяете присвоение этому псевдониму, на самом деле вы назначаете указанное место. Цель ссылки будет потеряна, если вы сможете указать ее в другом месте с помощью назначения.
Если последнее то, что вам нужно, вы должны использовать указатель.