В главе 1 мы сконструировали класс, позволяющий нам оперировать денежными суммами. Мы можем использовать тип TMoney почти так же, как и встроенные типы. Однако реализация операций не совсем удовлетворительна. Например, сложение было у нас реализовано следующим образом:
a=b.AddMoney(d);
Согласитесь, что сложение денежных сумм более естественно записать так: a=b+d;
Эту проблему можно решить за счет перегрузки операций (см. п. 13.5 в [1]). Перегрузка операций — это развитие механизма перегрузки функций и еще одно проявление полиморфизма в С++.
Нужно сказать, что в С++ мы постоянно пользуемся перегруженными операциями. Символ + (плюс) обозначает операцию сложения целых и дробных чисел. Этот же символ используется для обозначения операции сцепления строк типа st ri ng. Для вывода денежных сумм на экран мы использовали операцию <<, которая определена еще в С как операция сдвига влево. А операция присваивания по умолчанию перегружена вообще для всех типов данных, как встроенных, так и определяемых.
С++ во многом ограничивает перегрузку операций. Во-первых, разрешается перегружать только встроенные (табл. 3.1) операции (см. п. 5 в [1]) — новых определять нельзя. Во-вторых, даже встроенные операции разрешено перегружать не все. Запрещена перегрузка следующих операций: ? селектор компонента объекта (.);
? разыменование указателя на компонент класса (. *);
? условная операция (? :);
? указание области видимости (::);
? определение размера аргумента (si zeof).
Не допускается также перегрузка операций препроцессора # и ##.
В-третьих, операции можно перегружать только для нового типа данных — нельзя перегрузить операцию для встроенного типа. Например, нельзя перегрузить операцию А как операцию возведения в степень ни для double, ни для другого стандартного встроенного числового типа. Чтобы определить операцию возведения в степень, нам придется сначала объявить новый тип данных. В С++ новый тип данных можно образовать с помощью конструкций enum, union, struct и class.
Таблица 3.1. Операции С++ в порядке убывания приоритетов
Операция Назначение Использование
Область видимости ::name class::name
namespace::name
Селектор компонента класса object.member
-> Доступ к члену класса по указателю pointer -> member
[] Индексирование variable[expr]
0 Вызов функции function()
++ Инкремент постфиксный lvalue++
- Декремент постфиксный lvaluesizeof Размер объекта sizeof expr
sizeof Размер типа sizeof(type)
++ Префиксный инкремент ++lvalue
Префиксный декремент -lvalue
- Побитовое НЕ -expr
! Логическое НЕ lexpr
- Унарный минус -expr
+ Унарный плюс +expr
*. Разыменование *expr
& Адрес &expr
0 Приведение типа (type)expr
new Выделение памяти new type
new type(exprlist)
new[] Выделение памяти под массив new type[]
delete Освобождение памяти delete pointer
delete[] Освобождение памяти из-под массива delete[ ] pointer
->* Разыменование указателя на компонент pointer->*pointer_to_member
класса по указателю
* Разыменование указателя на компонент object.*pointer_to_member
класса
Операция Назначение Использование
* Умножение ехрг * ехрг
/ Деление' ехрг / ехрг
% Деление по модулю ехрг % ехрг
+ Сложение ехрг + ехрг
- Вычитание ехрг - ехрг
« Сдвиг влево ехрг « ехрг
» Сдвиг вправо ехрг » ехрг < Меньше ехрг < ехрг <= Меньше или равно ехрг <= ехрг > Больше ехрг > ехрг >= Больше или равно ехрг >= ехрг
== Равно ехрг == ехрг
!= Не равно ехрг != ехрг
& Побитовое И ехрг & ехрг
л Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ ехрг А ехрг
1 Побитовое ИЛИ ехрг | ехрг
&& Логическое И ехрг && ехрг
II Логическое ИЛИ ехрг || ехрг
?: Условная операция ехрг ? ехрг * ехрг
= Присваивание L-значение = ехрг
•-, /=.
+-. -=.«-,
»-, &=, к Составное присваивание (относительный порядок приоритетов соответствует порядку приоритетов операций без присваивания) L-значение += ехрг и т. д.
Запятая ехрг, ехрг
Операции можно перегружать либо как независимые внешние функции (и только такой способ перегрузки возможен для enum), либо как методы класса. Но и тут С++ имеет свои ограничения. Четыре операции допускается перегружать только методами класса: ? присваивание (=);
? вызов функции (());
? индексирование ([ ]);
? доступ по указателю (->).
Причем операция присваивания единственная создается системой автоматически, если не определена программистом явно. В офисных зданиях важно иметь генератор на случай отключения электроэнергии - http://www.gc-azimut.ru тут недорого.
Таким образом, эти операции в принципе нельзя перегрузить для конструкции enum. Однако и без перегрузки эти операции почти всегда корректно работают с новым типом. Остальные операции допускается перегружать как методами класса, так и независимыми внешними функциями.
Прототип функции-операции выглядит следующим образом: тип
operator@(cnncoK параметров);
Здесь @ — символ операции. Слово operator является зарезервированным словом и может использоваться только в определении или в функциональной форме вызова операции. Синтаксис и приоритет перегружаемой операции изменить нельзя. Это означает, что унарную операцию нельзя сделать при перегрузке бинарной и наоборот. Следовательно, при перегрузке унарных и бинарных операций нельзя использовать параметры по умолчанию. При перегрузке таких операций нет никакой возможности задать список параметров переменной длины. Единственная операция, которая не имеет фиксированного количества аргументов, — это операция вызова функции operator (). Остальные операции должны иметь либо один, либо два аргумента. Операции +, -, * и & допускается перегружать и как унарные, и как бинарные.
ООО "Группа компаний Азимут"
123458 Москва, ул. Кулакова 20, стр 1А.
тел. (495) 781-8472, 781-8473
www.gc-azimut.ru
Опубликовал Kest
August 30 2013 15:14:00 ·
0 Комментариев ·
4781 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.