Перегрузка операций
Перегрузка операций - это средство языка, позволяющее вводить
операции над типами, определяемыми пользователем. В 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;
Для перегрузки операций действуют следующие правила:
- Перегружать можно все операции за исключением
@
(взятие адреса),as
,is
,new
. Кроме того, можно перегружать специальные бинарные операции+=
,-=
,*=
,/=
, не возвращающие значений. - Перегружать можно только еще не перегруженные операции.
- Тип по крайней мере одного операнда должен совпадать с типом класса или записи, внутри которого определена операция.
- Перегрузка осуществляется с помощью статической функции-метода, количество параметров которой совпадает с количеством параметров соответствующей операции (2 - для бинарной, 1 - для унарной).
- Перегрузка операций
+=
,-=
,*=
,/=
для соответствующих операторов осуществляется с помощью статической процедуры-метода, первый параметр которой передается по ссылке и имеет тип записи или класса, в котором определяется данная операция, второй - передается по значению и совместим по присваиванию с первым. Перегрузка остальных операций осуществляется с помощью статических функций-методов. - Типы интерфейсов не могут быть типами параметров. Причина: типы параметров должны вычисляться на этапе компиляции.
- Операции приведения типа задаются статическими
функциями, у которых вместо имени используется
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;