Перегрузка операторов
Опция - перегрузка операторов предоставляет возможность назначать другие
действия для стандартных операторов языка. Так например оператору + определить
возможность возведения в степень или извлечение корня из числа. Конечно такая
возможность будет работать только с тем типом данных для которых предназначена
перегрузка, в остальных случаях это будет все тот же стандартный оператор . В
языке С++ перегрузка операторов может выполняться не на все операторы. Однако
сколько я не искал, в FreeBasic нигде не написано об таких вещах, возможно что
ограничений нет.
По своей сути перегрузку операторов лучше использовать
только тогда, когда это действительно облегчает читаемость программы, в
остальных случаях это будет несерьезно. Например, глупо использовать оператор +
как в примере ниже:
Type AA As Integer x End Type Operator + (l As AA) As String Return Str(l.x*l.x) End Operator Dim a As AA = Type(3) Dim b As AA = Type(5) Print +a Print +b Sleep
Данный код не может облегчать читаемость, более того он наверняка только запутает программиста, однако как возможный пример подойдет.
Я прошу прощения, что забыл в теме про структуры сообщить о возможности присваивать значения ее полям таким образом, как в примере выше. Запись:
Dim a As AA = Type(3)
полностью эквивалентна записи:
Dim a As AA a.x=3
Первое что нужно знать при перегрузке операторов: разные операторы
работают с разным кол-вом аргументов. Так например оператор минус и плюс могут
работать как с одним аргументом так и с двумя, а оператор равно только с двумя.
Отсюда важно понимать, сколько передавать параметров при перегрузке.
Второе,
что так же важно: перегрузка операторов не возможна без объявления своего
собственного типа. К этому типу будут привязаны объекты, использующие
перегруженные операторы. В нашем примере этим типом был тип AA. Все объекты,
созданные на базе этого типа, могут использовать перегруженные операторы, для
остальных типов данных это будет обычный оператор.
И наконец третье:
операторы при перегрузке разделяются как бы на два типа. Для одних не нужно
делать декларацию, поскольку они являются глобальными. Для другого типа
операторов использование похоже на использование методов класса.
Глобальные ( не нужно проводить декларацию):
- - (отрицание)
- Not (битовый отрицание)
- -> (указатель на область памяти)
- * (получение значения по адресу)
- + (сложение)
- - (вычитание)
- * (умножение)
- / (деление)
- \ (деление без остатка)
- & (объединение)
- Mod (модуль числа)
- Shl (битовый сдвиг влево)
- Shr (битовый сдвиг вправо)
- And (битовый И)
- Or (битовый ИЛИ)
- Xor (битовый исключающий ИЛИ)
- Imp (битовый импликация)
- Eqv (битовый эквивалент)
- ^ (степень числа)
- = (равно)
- <> (не равно)
- < (меньше)
- > (больше)
- <= (меньше или равно)
- >= (больше или равно)
Неглобальные (необходима декларация):
- Let (присвоение)
- Cast (преобразование)
- += (сложение и присвоение)
- -= (вычитание и присвоение)
- *= (умножение и присвоение)
- /= (деление и присвоение)
- \= (деление без остатка и присвоение)
- ^= (возведение в степень и присвоение)
- &= (объединение и присвоение)
- Mod= (модуль числа и присвоение)
- Shl= (сдвиг влево и присвоение)
- Shr= (сдвиг вправо и присвоение)
- And= (битовое И и присвоение)
- Or= (битовое ИЛИ и присвоение)
- Xor= (битовое исключающее ИЛИ и присвоение)
- Imp= (импликация и присвоение)
- Eqv= (эквивалент и присвоение)
Давайте вернемся к вышенаписанному примеру. Мы объявили свой тип данных AA. Далее на базе этого типа создали перегрузку оператора + . В данном случае этот оператор не декларируется, но параметр, который передается блоку должен иметь наш определяемый тип AA. Возвращаемое значение в примере строковое, но оно может быть любое по вашему усмотрению. В самом блоке можно проводить любые вычисления и преобразования. Ниже мы создали два объекта с типом AA , а далее использовали перегруженный оператор для этих объектов. Теперь тот же пример, только с двумя аргументами:
Type AA As Integer x End Type Operator + (l As AA , r As AA) As String Return Str(l.x*r.x) End Operator Dim a As AA = Type(3) Dim b As AA = Type(5) Print a+b Sleep
Как видите оператор + может работать как с одним аргументом, так и с двумя.
Можете заменить оператор + на оператор = разницы не будет. Но у вас не получится
проделать это в первом примере, поскольку оператор равно должен иметь 2
аргумента.
Теперь я предлагаю пример с использованием декларации неглобальных
операторов:
Type AA As Integer x Declare Operator ^= (l As AA) End Type Operator AA.^= (l As AA) x = l.x^3 End Operator Dim As AA a = (2), b = (3) a ^= b b ^= a Print a.x Print b.x Sleep
Данный пример является перегрузкой оператора ^= . Его назначение в этом
примере возведение в степень тройки. Какие бы значения мы не присваивали полям
объектов, они при использовании этого оператора, будут возводится в
степень тройки. В примере нет ничего сложного. Перегруженный оператор
декларируется и объявляется как метод класса. В остальном все так же как с
глобальными операторами.
Я понимаю, что данные примеры не показывают
полезности перегрузки операторов. На самом деле я не считаю данную фичу чем-то
полезным. На мой взгляд это лишнее извращение в коде. Однако это только мое
субъективное мнение, возможно вы найдете применение этой возможности в ваших
программах.
Всего доброго!
содержание | назад | вперед