Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП Лекции PDF / ООП 08 Лек Перегрузка операторов.pdf
Скачиваний:
72
Добавлен:
15.02.2015
Размер:
403.59 Кб
Скачать

Лекция 8

Перегрузка операторов

4

}

Результат работы программы с перегруженными таким образом операторами будет тем же.

Перегрузка оператора присваивания

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

операторная функция оператора присваивания не может быть объявлена как глобальная функция (функция, не являющаяся членом класса);

операторная функция оператора присваивания не наследуется производным классом;

компилятор может сгенерировать операторную функцию оператора присваивания, если она не определена в классе.

Оператор присваивания по умолчанию, сгенерированный компилятором, выполняет почленное присваивание нестатических членов класса. Здесь та же ситуация, что и с генерируемым компилятором конструктором копирования по умолчанию: результат окажется непригодным для использования, если класс содержит указатели.

Хотя в нашем классе Dot указатели отсутствуют, но класс содержит константный член name, который не может изменяться после инициализации. Поэтому оператор присваивания по умолчанию будет вызывать синтаксическую ошибку.

Необходимо отметить, что левый операнд после выполнения оператора присваивания меняется, так как ему присваивается новое значение. Поэтому функция оператора присваивания должна возвращать ссылку на объект, для которого она вызвана (и которому присваивается значение), если мы хотим сохранить семантику оператора присваивания для встроенных типов данных. Проще всего это сделать, возвратив разыменованный указатель this. Это, в частности, позволяет использовать перегруженный оператор присваивания в выражениях следующего вида:

D1 = D2 = D3 ;

Следующий пример иллюстрирует, как осуществляется перегрузка оператора присваивания:

class Dot

Файл Dot.h

// класс точки

{

 

• • •

 

public:

 

Dot& operator = ( Dot & R ) ;

// перегрузка оператора присваивания

};

Файл Dot.cpp

#include ”Dot.h”

 

• •

//реализация перегруженного оператора присваивания

Dot & Dot :: operator = ( Dot & R )

{

if ( this == &R ) return *this ;

x = R.x ;

y = R.y ;

return *this ;

 

}

Заметим, что при реализации перегруженного оператора необходимо проводить проверку на присваивание самому себе. Если в коде программы встретится строка вида

D = D ;

или, что гораздо более вероятно, нечто вроде следующего:

Coord D , *pD ;

D = *рD ;

При этом произойдет присваивание самому себе, связанное с ошибкой в программе.

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

В приведенном выше примере функция operator = ( ) содержит инструкцию if ( this = &R ) return *this ;

Здесь идентификатор R используется для обозначения операнда, расположенного в правой части оператора присваивания.

Выжол Ю.А.

Объектно-ориентированное программирование