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. |