Добрый день
Существует ли список в FP, как встроенный тип?
говорят что да но найти о нем в руководстве не могу ни слова
uses classes;
type
PT = ^T;
T = record
X, Y: integer;
end;
function compare(a, b: pointer): integer;
begin
if PT(a)^.X > PT(b)^.X then compare := 1
else
if PT(a)^.X < PT(b)^.X then compare := -1
else compare := PT(a)^.Y - PT(b)^.Y;
end;
procedure print(p: pointer);
begin
with PT(p)^ do begin
writeLn('X = ', X:2, ' Y = ', Y:2);
end;
end;
procedure incr(p: pointer);
begin
with PT(p)^ do begin
inc(X); inc(Y);
end;
end;
var
p: PT;
my_list: TFPList;
i: integer;
begin
my_list := TFPList.Create();
for i := 1 to 10 do begin
new(p);
with(p^) do begin
X := random(15); y := random(15);
writeLn('X = ', X:2, ' Y = ', Y:2);
end;
my_list.add(p);
end;
writeln('for each');
my_list.foreachcall(@incr, nil);
my_list.foreachcall(@print, nil);
writeln('sorting');
my_list.sort(@compare);
my_list.foreachcall(@print, nil);
// здесь удалить все элементы и сам список
end.
{$mode objfpc}
uses classes;
type
PT = ^T;
T = record
X, Y: integer;
end;
function compare(a, b: pointer): integer;
begin
if PT(a)^.X > PT(b)^.X then compare := 1
else
if PT(a)^.X < PT(b)^.X then compare := -1
else compare := PT(a)^.Y - PT(b)^.Y;
end;
procedure print(p: pointer; arg: pointer); // Еще один параметр
begin
with PT(p)^ do begin
writeLn('X = ', X:2, ' Y = ', Y:2);
end;
end;
procedure incr(p: pointer; arg: pointer); // И здесь тоже ...
begin
with PT(p)^ do begin
inc(X); inc(Y);
end;
end;
var
p: PT;
my_list: TFPList;
i: integer;
begin
my_list := TFPList.Create();
for i := 1 to 10 do begin
new(p);
with(p^) do begin
X := random(15); y := random(15);
writeLn('X = ', X:2, ' Y = ', Y:2);
end;
my_list.add(p);
end;
writeln('for each');
my_list.foreachcall(@incr, nil);
my_list.foreachcall(@print, nil);
writeln('sorting');
my_list.sort(@compare);
my_list.foreachcall(@print, nil);
end.
my_list.foreachcall(@incr, nil);//для каждого элемента my_list вызываем эту процедурузачем передавать nil?
procedure incr(p: pointer; arg: pointer);
//получаем 2 аргумента первый указатель на процедуру,
// второй -- не ясно что...
begin
with PT(p)^ do begin // PT(p)^ ? р-- это ж ведь указатель на процедуру, а не на ячейку или список...
inc(X); inc(Y);
end;
end;
my_list.foreachcall(@incr, nil);
//вызов процедуры
procedure incr(p: pointer; arg: pointer); // И здесь тоже ...
//реализация процедуры
begin
with PT(p)^ do begin
inc(X); inc(Y);
end;
end;
procedure TFPList.ForEachCall(proc2call:TListCallback;arg:pointer);
//реализация метода(исходники)
var
i : integer;
p : pointer;
begin
For I:=0 To Count-1 Do
begin
p:=FList^[i];
if assigned(p) then
proc2call(p,arg);
end;
end;
type TListCallback = procedure(
//реализация типа (документация)
data: pointer; //Data pointer from the list.
arg: pointer // Parameter passed to the ForEachCall call. /не нужный параметр?
) of object;
{private class} procedure C.Metod2(const Node:TNode);
var
p: ^TNode;
begin
new(p);
p^:=Node;
self.List.Add(p);
end;
TNode = record
U:UserTipe;;
end;
{private class} procedure C.Metod2();получаю набор ошибок... в модуле использую {$STATIC ON} и {$mode objfpc}.
var
SomeU:UserTipe;
begin
SomeU:=self.List[0].TNode.U;//сохраняем поле обьекта <---ОШИБКА!!!
MySnake(MyList[0]).Free; //освобождаем объект
MyList.Delete(0); //удаляем ссылку на него
end;
SomeU := PUser(List[0])^;, где PUser = ^UserTipe;
SomeU := PUser(List[0])^;, где PUser = ^UserTipe;
procedure MyC.Metod2();
type
PUser = ^UserTipe; // <-- Хотя это желательно сделать при описании типа UserTipe, в том же модуле
var
SomeU: UserTipe;
begin
SomeU := PUser(List[0])^;
...
{...}implementation{...}
procedure MyC.Metod2();
var
SomeU:UserTipe;
begin
SomeU := PUser(List[0])^; //тут, благодаря тебе, работает..
self.List[0].Free; //а тут нет
//необходимо отчищать память где находилось то на что указывал указатель, но как?
self.List.Delete(0);
end;
end.
type
PUser = ^UserTipe;
UserTipe = object
x: integer;
destructor done;
end;
implementation
destructor UserTipe.Done;
begin
// Пока можно оставить пустым
end;
Не нужно Self все время за собой таскать, компилятор и так разберется...
...
procedure MyC.Metod2();
var
SomeU: UserTipe;
begin
SomeU := PUser(List[0])^; // Сохраняем данные
Dispose(PUser(List[0]), Done); // Удаляем объект по указателю ...
List.Delete(0); // ... и сам указатель
end;
...
procedure MyC.Metod2();
var
SomeU: UserTipe;
L: PUser;
begin
SomeU := PUser(List[0])^;
writeln(someu.X);
L := List[0];
Dispose(L); // Это удалит все, что надо - проверено с использованием heaptrc
List.Delete(0);
end;