8.9 Перегрузка операторов и дженерики

Вверх  Предыдущий  Следующий

Перегрузка операторов (глава Глава 15 Перегрузка операторов) и дженерики тесно связаны между собой. Представьте себе обычный класс, который имеет следующее определение:

{$mode objfpc}

unit mya;

 

interface

 

type

  Generic TMyClass<T> = Class(TObject)

    Function Add(A,B : T) : T;

  end;

 

Implementation

 

Function TMyClass.Add(A,B : T) : T;

begin

  Result:=A+B;

end;

 

end.

Когда компилятор воспроизводит макрос дженерика, сложение должно быть возможным. Для такой специализации:

TMyIntegerClass = specialize TMyClass<integer>;

что не является проблемой, так как метод Add может быть определен:

Procedure TMyIntegerClass.Add(A,B : Integer) : Integer;

begin

  Result:=A+B;

end;

Компилятор знает, как сложить два целых числа, так что этот код будет скомпилирован без проблем. Но следующий код:

Type

  TComplex = record

    Re,Im : Double;

  end;

 

Type

  TMyIntegerClass = specialize TMyClass<TComplex>;

не скомпилируется, если сложение двух типов TComplex не определено. Это может быть сделано с помощью операторов действий над записями:

{$modeswitch advancedrecords}

uses mya;

 

Type

   TComplex = record

     Re,Im : Double;

     class operator +(a,b : TComplex) : TComplex;

   end;

 

class operator TComplex.+ (a,b : TComplex) : TComplex;

begin

   Result.re:=A.re+B.re;

   Result.im:=A.im+B.im;

end;

 

Type

   TMyComplexClass = specialize TMyClass<TComplex>;

 

begin

   // код

end.

В настоящее время, из-за ограничений реализации, они (операции с записями) не будут работать с использованием глобального оператора, то есть следующий код пока не работает:

uses mya;

 

Type

   TComplex = record

     Re,Im : Double;

   end;

 

operator + (a,b : TComplex) : TComplex;

begin

   Result.re:=A.re+B.re;

   Result.im:=A.im+B.im;

end;

 

Type

   TMyComplexClass = specialize TMyClass<TComplex>;

 

begin

   // код

end.

Поддержка этой конструкции ожидается в будущих версиях Free Pascal.