Статья: Классы: копирование и присваивание
private:
int data;
char moreData;
float no_Pointers;
};
Если хотя бы одно из названных условий не выполняется, то следует опре-делить как конструктор копий, так и операцию присваивания.
Определение операции присваивания
По функциональному назначению операция присваивания очень похожа на конструктор копий. Принципиальное отличие состоит в том, что конструктор копий создает новый (возможно, временный) объект, а операция присваивания работает с уже созданными. Вызывающий объект является левым операндом, объект-аргумент - правым.
Операция присваивания также имеет соответствующий синтаксис. Операция присваивания - это функция-член и одновременно двухместная операция. Следовательно, в работу вовлечены два объекта. Первый объект - вызывающий, доступный по указателю this, а второй - это аргумент. Как конструктор копий, так и операция присваивания используют в качестве аргумента постоянную ссылку.
Для произвольного класса X мы имеем следующий синтаксис операции присваивания:
X& operator=(const X&); // синтаксис операции присваивания для
// произвольного класса
Присваивание - это операция, значит мы должны использовать ключевое слово operator и соответствующий символ операции. Так как C++ допускает цепочки присваивания а = b = с = d;
// C++ допускает последовательные присваивания,
// так что это свойство надо сохранить,
то необходимо возвращать ссылку на объект; в противном случае цепочка прервется.
Итак, оператор-функция принимает постоянную ссылку, а возвращает ссылку на объект. Использование ключевого слова const позволяет функции работать как с постоянными объектами, так и с переменными.
Определяя новый класс, если вы решили объявить операцию присваивания, следуйте следующим рекомендациям:
Операция присваивания должна быть членом класса.
Она принимает постоянную ссылку на объект типа того же класса.
Она возвращает ссылку на объект типа того же класса.
Проверка на присваивание самому себе.
В операции присваивания для любого класса надо учитывать один важный момент. Всегда надо проверять: не происходит ли присваивания самому себе. Оно может иметь место в том случае, когда объект прямо или косвенно вызывает операцию присваивания для себя. Прямое присваивание может выглядеть следующим образом:
POINT Pix;
Pix = Pix; // присваивание самому себе
Это самый тривиальный случай, он хорош для приведения примера, не более. В реальных программах такого обычно не бывает и эта ошибка, как правило, принимает далеко не столь очевидные обличия.
Присваивание самому себе порож-дает в программе утечки памяти. Такая ситуация может возникнуть, когда два объекта сообща используют некоторый ресурс и один из них этот ресурс освобождает. При этом состояние ресурса становится неопределенным, но второй объект продолжает на него ссылаться.
Есть много путей, ведущих к возникновению этой проблемы. Для ее предотвращения и следует предусмотреть в операции присваивания проверку на присваивание самому себе. Она очень проста и выглядит всегда совершенно одинаково:
POINT& POINT::operator=(const POINT& rhs)