gpt4 book ai didi

class - Delphi 类 TList

转载 作者:行者123 更新时间:2023-12-03 15:20:56 28 4
gpt4 key购买 nike

我创建了一个简单的类,将对象保存在通用列表中。我设法让它工作。但我不明白为什么这不起作用。

for Monster in MonsterList do
begin
Monster.Free;
MonsterList.Remove(Monster);
end;

如果我尝试从 MonsterList 中释放和删除这样的项目,它并没有真正删除,在我的例子中,名称消失了,但强度值保留在那里。如果我随后尝试列出 MonsterList 的内容,我总是会留下一项。所以我用谷歌搜索了一下,并在 Stack-overflow 上找到了一个好的解决方案,那就是简单地倒计时。

另一件事是,当我将 Monsters 添加到 MonsterList 时,我添加了 3 个 Items ,但是如果我调试,我会看到 MonsterList 实际上有 0,1,2,3 3 为 NULL仅当我添加所有三个对象时才会发生这种情况,如果我只添加两个对象,它不会创建最终的 NULL 指针。这是某种优化的开始吗?

整个代码(不多)

unit MainForm;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Generics.Collections, Generics.Defaults,
System.Types;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMonster = class
private
fName : string;
fStrength : integer;
fisDead : boolean;
public
constructor Create(Name : string; Strength : integer);
destructor Destroy; override;

property Name : string read fName write fName;
property Strength : integer read fStrength write fStrength;
property isDead : boolean read fisDead write fisDead;
end;

var
Form1: TForm1;
MonsterList : TList<TMonster>;
MonsterInstances : integer = 0;


implementation

{$R *.dfm}

constructor TMonster.Create(Name: string; Strength: integer);
begin

inc(MonsterInstances);

fName := Name;
fStrength := Strength;
fisDead := false;
end;

destructor TMonster.Destroy;
begin
dec(MonsterInstances);

inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Monster : TMonster;
i : integer;
begin
MonsterList := TList<TMonster>.Create;

Memo2.Lines.Add(inttostr(MonsterInstances));

MonsterList.Add(TMonster.Create('Jill',10));
MonsterList.Add(TMonster.Create('Jane',1));
MonsterList.Add(TMonster.Create('Rob',20));

Memo2.Lines.Add(inttostr(MonsterInstances));

for Monster in MonsterList do
begin
Memo1.Lines.Add(Monster.fName+ ' Strenght '+inttostr(Monster.fStrength)+' IsDead= '+booltostr(Monster.fisDead))
end;

MonsterList[1].isDead:=true;

// not working
{for Monster in MonsterList do
begin
Monster.Free;
MonsterList.Remove(Monster);
end; }

// works
for i := MonsterList.Count-1 downto 0 do
begin
if MonsterList[i].isDead = true then
begin
MonsterList[i].Free;
MonsterList.Delete(i);
MonsterList.Capacity:=MonsterList.Capacity-1;
end;
end;

Memo1.Lines.Add('Survivors :');

for Monster in MonsterList do
Memo1.Lines.Add(Monster.Name+' Strenght '+inttostr(Monster.Strength));


ShowMessage(inttostr(MonsterInstances));

end;

end.

谢谢!

最佳答案

您无法在像这样迭代列表时修改列表。相反,释放所有成员,然后清除列表。

for Monster in MonsterList do
Monster.Free;
MonsterList.Clear;

这还有一个额外的好处,就是不调用 Remove这会花时间搜索该项目。

也许更简单的是使用 TObjectList<T>并允许集合管理其成员的生命周期。那么您只需调用Clear即可只要 OwnsObjectsTrue所有成员将被销毁,列表被清除。

就你的第二个问题而言,如果你添加三个项目,则有索引为 0、1 和 2 的项目。没有索引为 3 的项目。现在,集合在内部很可能使用一个已结束的内部数组分配。因此私有(private)内部数组可以有一个索引 3。但是该内部数组的内容对您来说应该不重要。

关于class - Delphi 类 TList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50830198/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com