Перегрузка операций

Перегрузка операций - это средство языка, позволяющее вводить операции над типами, определяемыми пользователем. В PascalABC.NET можно использовать только предопределенные значки операций. Перегрузка операций для типа T, являющегося классом или записью, осуществляется при помощи статической (классовой) функции-метода со специальным именем operator ЗнакОперации. Перегрузка специальных операций +=, -=, *=, /= осуществляется с помощью статической (классовой) процедуры-метода, первый параметр которой передается по ссылке.

Например:

type
  Complex = record
    re,im: real;
    class function operator+(a,b: Complex): Complex;
    begin
      Result.re := a.re + b.re;
      Result.im := a.im + b.im;
    end;
    class function operator=(a,b: Complex): boolean;
    begin
      Result := (a.re = b.re) and (a.im = b.im);
    end;
  end;

Для перегрузки операций действуют следующие правила:

  1. Перегружать можно все операции за исключением @ (взятие адреса), as, is, new. Кроме того, можно перегружать специальные бинарные операции +=, -=, *=, /=, не возвращающие значений.
  2. Перегружать можно только еще не перегруженные операции.
  3. Тип по крайней мере одного операнда должен совпадать с типом класса или записи, внутри которого определена операция.
  4. Перегрузка осуществляется с помощью статической функции-метода, количество параметров которой совпадает с количеством параметров соответствующей операции (2 - для бинарной, 1 - для унарной).
  5. Перегрузка операций +=, -=, *=, /= для соответствующих операторов осуществляется с помощью статической процедуры-метода, первый параметр которой передается по ссылке и имеет тип записи или класса, в котором определяется данная операция, второй - передается по значению и совместим по присваиванию с первым. Перегрузка остальных операций осуществляется с помощью статических функций-методов.
  6. Типы интерфейсов не могут быть типами параметров. Причина: типы параметров должны вычисляться на этапе компиляции.
  7. Операции приведения типа задаются статическими функциями, у которых вместо имени используется operator implicit (для неявного приведения типа) или operator explicit (для явного приведения типа).

Например:

type
  Complex = record
    ...
    class function operator implicit(d: real): Complex;
    begin
      Result.re := d;
      Result.im := 0;
    end;
    class function operator explicit(c: Complex): string;
    begin
      Result := Format('({0},{1})',c.re,c.im);
    end;
    class procedure operator+=(var c: Complex; value: Complex);
    begin
      c.re += value.re;
      c.im += value.im;
    end;
    class function operator+(c,c1: Complex): Complex;
    begin     
      Result.re := c.re + c1.re;
      Result.im := c.im + c1.im;
    end;
  end;

Можно перегружать операции с помощью методов расширения - в этом случае при описании подпрограммы не писать слово class. Например, так в системном модуле реализовано добавление числа к строке:

function string.operator+(str: string; n: integer): string;
begin
  result := str + n.ToString;
end;