Не секрет, что во free pascal'е существует возможность перегрузки стандартных операторов. В документации говорится, что есть три типа таких операторов:
1) Арифметические бинарные (+, *, <>, /, **) - любая функция от двух параметров.
2) Операции сравнения (<, >, =, <=, >=) - функция от двух переменных, возвращающая Boolean, причем <> будет сгенерирован автоматически как отрицание к =.
3) Оператор присваивания (:=) - функция принимающая значение одного типа и возвращающая значение другого типа.
Работает это примерно так
Type
TVec3D = Array[0..2] Of Double;
// Скалярное произведение
operator * (A, B: TVec3D) Result: Double;
Var
I: Integer;
begin
Result := 0;
for I := 0 to 2 do
Result += A[I] * B[I];
end;
// Угол от A к B в плоскости XY по часовой?
operator > (A, B: TVec3D) Result: Boolean;
begin
Result := A[0]*B[1] - A[1]*B[0] >= 0;
end;
// Присвоение числа в вектор
operator := (V: Integer) Result: TVec3D;
Var
I: Integer;
begin
for I := 0 to 2 do
Result[I] := V;
end;
Однако, если покапаться в исходниках free pascal'я (я экспериментировал с 2.2.2, в более поздних версиях что-то может быть не так), то можно обнаружить, что перегрузке поддаются еще и операторы
1) Арифметические ><, or, and, div, mod, shl, shr, xor.
2) Унарные -, not.
Оператор >< в самом языке используется для нахождения симметрической разности двух множеств. Т.е. код
Var
I: Integer;
S: Set Of Byte;
...
S := [1, 2, 3, 4, 5] >< [3, 4, 5, 6, 7];
for I := 1 to 7 do
Write(Ord(I in S));
Writeln;
напечатает 1100011, а в переменной S будет [1, 2, 6, 7].
Его очень удобно использовать для обозначения векторного произведения (чем, кстати и воспользовались разработчики free pascal'я в своем модуле matrix).
mod очень кстати заюзать для создания собственного удобного нахождения остатков.
Согласно комментариям в модуле tockens исходников компилятора перегрузке должны поддаваться еще и as, in, is. Однако, у меня этого сделать почему-то не вышло, наверно к ним нужен какой-то особый подход. Никто не знает какой именно? :)
Комментариев нет:
Отправить комментарий