Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры / ООП(Тимофеев) / ООП-Тимофеев.doc
Скачиваний:
45
Добавлен:
16.04.2013
Размер:
328.19 Кб
Скачать

Перегрузка бинарных операторов

Вернемся к нашему примеру clock и покажем, как перегрузить бинарные опе­раторы. В основном, поддерживаются те же принципы. Когда бинарный опе­ратор перегружается с помощью функции-члена, он получает в качестве первого аргумента неявно передаваемую переменную класса, а в качестве второго аргу­мента — единственный аргумент списка параметров. Дружественные функции и обычные функции получают оба аргумента из списка параметров (отсутствует неявный аргумент). Конечно, обычные функции не имеют доступа к закрытым членам.

Создадим операцию для типа clock, которая складывает два значения.

class clock { . . . . . friend clock operator +(clock c1, clock c2) ; };

clock operator+(clock cl, clock c2)

{ return (cl.tot_secs + c2.tot_secs) ; }

Целое выражение неявно преобразуется к типу clock с помощью преобразующего конструктора clock ::clock (unsigned long). Оба значения типа с lock передаются как аргументы функции, и оба они являются кандидатами для преобразования при присваивании. Поскольку operator+ () является симметричным бинарным оператором, аргументы должны трактоваться одинаково. Таким образом, обыкно­венно симметричные бинарные операторы перегружаются дружественными функ­циями.

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

Оператор присваивания для типа класса по умолчанию генерируется компилятором для выполнения почленного присваивания. Это прекрасно, когда подходит поверхностное копирование. Для типов вроде my_string или vect, которые

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

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

Обновленный класс будет содержать несколько улучшений, делающих его более безопасным и полезным. Будет до6авлен конструктор, преобразующий обычный целый массив в безопасный массив. Это позволит нам написать код, использующий безопасные массивы, а затем эффективно применять этот код с обычными массивами. Наконец, оператор индексирования перегружается и заменяет функцию-член . Перегруженный оператор индексирования может иметь любой возвращаемый тип и любой тип списка аргументов.

Перегруженные операторы ввода-вывода « и »

Сохраняя дух ООП, важно перегрузить оператор «, чтобы выводить пользователь­ские типы, так же как и собственные. Оператор « имеет два аргумента: ostream& и АТД, и должен создавать ostream&. Используется ссылка на поток и возвращается ссылка на поток (вне зависимости от того, что перегружается — « или »), потому, что мы не хотим копировать объект потока.

Перегрузка оператора » для вывода пользовательского типа обычно выглядит так:

istream& operator»(istream& р, пользовательский_тип& x)

Если функции необходим доступ к закрытым членам x, ее надо сделать дружественной к этому классу. Ключевой момент здесь — сделать х параметром-ссылкой, чтобы его значение можно было изменять. Для этого в классе необходимо поместить объявление friend для этого оператора и обеспечить определение его функции: istream& operator»(istream& in, rational& x)

{ return (in » x.a » x.q); }

Соседние файлы в папке ООП(Тимофеев)