406 ______ Часть III. Современное программирование на C++

Определяя новый класс, сразу же объявляйте операцию присваивания, следуя следующим рекомендациям:

• Операция присваивания должна быть членом класса.

• Она возвращает ссылку на объект типа того же класса.

• Эта функция называется operator^.

• Она принимает постоянную ссылку на объект типа того же класса. Использование ключевого слова const позволяет функции работать как с постоянными объектами, так и с переменными.

Проверка на присваивание самому себе. В операции присваивания любого класса надо учитывать один важный момент. Всегда надо проверять: не происходит ли присваивания самому себе; оно может иметь место в том случае, когда объект прямо или косвенно вызывает операцию присваивания для себя. Прямое присваивание может выглядеть следующим образом:

Х х;

х = х; // присваивание себе

Это тривиальный случай; в реальных программах эта ошибка, как правило, принимает далеко не столь очевидные обличия. Присваивание себе порождает в программе утечки памяти. Такая ситуация может возникнуть, когда два объекта сообща используют некоторый ресурс и один из них этот ресурс освобождает. При этом состояние ресурса становится неопределенным, но второй объект продолжает на него ссылаться.

Есть много путей, ведущих к возникновению этой проблемы. Для ее предотвращения следует предусмотреть в операции присваивания проверку на присваивание самому себе. Она очень проста и выглядит всегда совершенно одинаково:

Х& X::operator=(const X& rhs) {

if ( this =^ &rhs) return *this; // проверка на присваивание себе // ... остальное

return *this; // возврат ссылки на объект i

Пояснения. В предыдущем разделе был рассмотрен синтаксис проверки на присваивание самому себе. Сейчас мы попробуем в ней разобраться, благо для всех операций присваивания проверка на присваивание себе совершенно одинакова. ,

Оператор

if ( this == &rhs)

проверяет, не совпадает ли аргумент с самим объектом. Указатель this содержит адрес вызывающего объекта, &rhs читается как "адрес rhs". Таким