| Перегрузка операций FPC 2.0.x | |||
| Зачем это нужно | Как это сделать? | Примеры использования | |
| Перегрузка функций | Вычисление многочлена матрицы | Реализация "больших" множеств | |
| Вычисление квадратного корня из матрицы | |||
Зачем это нужно?
Очень часто при работе с типами данных, определенных пользователями, не хватает возможности работать с этими типами, как со встроенными в язык, т.е., например для сложения матриц не использовать вызов процедурыMatrixAdd(C, A, B);, а записать эту операцию в виде
C := A + B;
If isEqual(mx, mxO) or isEqual(mx, mxE), а
If (mx = mxO) or (mx = mxE)...
Как это сделать?
Прежде всего - чтобы перегрузка была доступна, программа (или модуль, если это делается в модуле) должна компилироваться с ключом {$mode objfpc}. При использовании модулей директива {$mode objfpc} обязательна только для модуля, содержащего реализацию перегрузки, вызывающая программа может такой директивы не иметь...Operator + (Const m1, m2: TMatrix) R: TMatrix;
Begin
{ Заполняем матрицу R нужными значениями, и она вернется как результат операции }
End;Var A, B, C: TMatrix;
Begin
...
C := A + B; { матрица - сумма присвоится переменной C }
...
End.Перегрузка функций
function test(a: integer): integer;
begin
result := 0;
end;
{ Разрешено - список параметров отличается от списка предыдущей функции }
function test(a: double): integer;
begin
result := 0;
end;
{ Ошибка: несмотря на то, что тип результата другой, списки параметров одинаковы, а это недопустимо }
function test(a: integer): double;
begin
result := 0.0;
end;operator + (const mx1, mx2: TMatrix) r: TMatrix;
var i, j: integer;
begin
for i := 1 to n do
for j := 1 to n do
r[i, j] := mx1[i, j] + mx2[i, j];
end;operator + (const mx: TMatrix; const X: integer) r: TMatrix;
var i, j: integer;
begin
for i := 1 to n do
for j := 1 to n do
r[i, j] := mx[i, j] + X;
end;Var A, B, C: TMatrix; Begin A := A + 2; C := A + B; End.
A := A + 2;это совсем не значит, что можно сделать и
A := 2 + A;
operator + (const X: integer; const mx: TMatrix) r: TMatrix;
begin
r := mx + X; { Пользуемся уже определенным сложением с другим порядком операндов }
end;Примеры использования:
1. Вычисление многочлена матрицы
{$mode objfpc}
const
size = 4;
type
TMatrix = array[1 .. size, 1 .. size] of double;
operator * (const a, b: TMatrix) m: TMatrix;
var i, j, k: integer;
begin
for i := 1 to size do
for j := 1 to size do begin
m[i, j] := 0;
for k := 1 to size do
m[i, j] := m[i, j] + a[i, k] * b[k, j]
end;
end;
operator * (const a: TMatrix; const f: double) m: TMatrix;
var i, j: integer;
begin
for i := 1 to size do
for j := 1 to size do
m[i, j] := f * a[i, j]
end;
operator + (const a, b: TMatrix) m: TMatrix;
var i, j: integer;
begin
for i := 1 to size do
for j := 1 to size do
m[i, j] := a[i, j] + b[i, j]
end;
{ Возведение матрицы в степень }
operator ** (const a: TMatrix; const pow: integer) m: TMatrix;
var i, j: Integer;
begin
if pow = 0 then begin
for i := 1 to size do
for j := 1 to size do
m[i, j] := Byte(i = j);
exit
end;
m := a;
for i := 1 to pred(pow) do
m := m * a;
end;
procedure matrixPrint(a: TMatrix);
var i, j: integer;
begin
for i := 1 to size do begin
for j := 1 to size do
write(a[i, j]:9:2);
writeln
end
end;
const
n = 3;
p: array[1 .. n] of double = (1.0, -2.0, 3.0);
const
a: TMatrix = (
(10, 11, 14, 16),
(12, 17, 10, 16),
( 8, 12, 12, 7),
( 8, 5, 17, 1)
);
var
Res: TMatrix;
i: Integer;
begin
matrixPrint(a);
for i := 1 to n do
res := res + (a ** (n - i)) * p[i]; { Все вычисление записывается в одну строчку }
matrixPrint(Res)
end.