Class Delphi类TList
我创建了一个简单的类,将对象保存在一个通用列表中。我设法使它工作起来。但我不明白这为什么不起作用Class Delphi类TList,class,delphi,generics,foreach,Class,Delphi,Generics,Foreach,我创建了一个简单的类,将对象保存在一个通用列表中。我设法使它工作起来。但我不明白这为什么不起作用 for Monster in MonsterList do begin Monster.Free; MonsterList.Remove(Monster); end; 如果我尝试从怪物列表中释放并移除类似的物品,它不会真正移除,在我的例子中,名称消失了,但强度值仍然存在。如果我试着在之后列出怪物列表的内容,我总是会留下一个项目。所以我在谷歌上搜索了一下,发现
for Monster in MonsterList do
begin
Monster.Free;
MonsterList.Remove(Monster);
end;
如果我尝试从怪物列表中释放并移除类似的物品,它不会真正移除,在我的例子中,名称消失了,但强度值仍然存在。如果我试着在之后列出怪物列表的内容,我总是会留下一个项目。所以我在谷歌上搜索了一下,发现这里的堆栈溢出是一个很好的解决方案,就是简单地倒计时
另一件事是,当我将怪物添加到怪物列表时,我添加了3项,但如果我调试,我会看到怪物列表实际上有0,1,2,33为空
这只有在我添加所有三个对象时才会发生,如果我只添加两个对象,它不会创建最终的空指针。这是某种优化吗
整个代码(不多)
unitmainform;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
控件、窗体、对话框、StdCtrls、泛型、集合、泛型、默认值、,
系统、类型;
类型
TForm1=类(TForm)
按钮1:t按钮;
备忘录1:TMemo;
备忘录2:TMemo;
程序按钮1点击(发送方:ToObject);
私有的
{私有声明}
公众的
{公开声明}
结束;
TMonster=类
私有的
fName:字符串;
fStrength:整数;
fisDead:布尔;
公众的
构造函数创建(名称:字符串;强度:整数);
毁灭者毁灭;推翻
属性名称:字符串读取fName写入fName;
属性强度:整数读fStrength写fStrength;
属性isDead:布尔读取fisDead写入fisDead;
结束;
变量
表1:TForm1;
怪物列表:TList;
实例:整数=0;
实施
{$R*.dfm}
构造函数TMonster.Create(名称:字符串;强度:整数);
开始
公司(实例);
fName:=名称;
F强度:=强度;
fisDead:=假;
结束;
析构函数TMonster.Destroy;
开始
12月(5日);
继承;
结束;
程序TForm1.按钮1单击(发送方:TObject);
变种怪物:特蒙斯特;
i:整数;
开始
怪物列表:=TList.Create;
备忘录2.Lines.Add(inttostr(实例));
添加(TMonster.Create('Jill',10));
添加(TMonster.Create('Jane',1));
添加(TMonster.Create('Rob',20));
备忘录2.Lines.Add(inttostr(实例));
怪物列表中的怪物怎么办
开始
备忘录1.Lines.Add(Monster.fName+'strength'+inttostr(Monster.fStrength)+'IsDead='+booltostr(Monster.fisDead))
结束;
怪物列表[1]。isDead:=true;
//不起作用
{对于怪物列表中的怪物,请执行以下操作:
开始
怪物。自由;
怪物列表。移除(怪物);
结束;}
//工作
对于i:=MonsterList.Count-1到0 do
开始
如果MonsterList[i].isDead=true,则
开始
怪物列表[i]。免费;
删除(i);
MonsterList.Capacity:=MonsterList.Capacity-1;
结束;
结束;
备忘录1.行。添加('幸存者:');
怪物列表中的怪物怎么办
备忘录1.Lines.Add(Monster.Name+‘Strength’+inttostr(Monster.Strength));
ShowMessage(inttostr(MonsterInstances));
结束;
结束。
谢谢大家! 在这样迭代列表时,不能修改列表。相反,释放所有成员,然后清除列表
for Monster in MonsterList do
Monster.Free;
MonsterList.Clear;
这样做的另一个优点是不调用Remove
,这会花费时间搜索项目
也许更简单的方法是使用TObjectList
,并允许集合管理其成员的生命周期。然后您只需调用Clear
,只要OwnsObjects
为True
所有成员都将被销毁,列表将被清除
就第二期而言,如果添加三个项目,则会有索引为0、1和2的项目。没有索引为3的项。现在,在内部,集合可能会使用过度分配的内部数组。这样私有内部数组就可以有一个索引3。但该内部数组的内容对您来说并不重要在一个循环中移除列表项不是一个好主意。在使用类时,你应该考虑使用TojjCtLeT而不是TTLIST,这样你就不必费心释放你的项目了。在任何情况下,如果没有特定的理由,都不应该干扰列表的容量。ObjectList看起来比列表更有希望。非常感谢。请记住,如果列表拥有所有权,则在调用Remove或Delete时,它将自动销毁对象—如果您希望避免使用Extract。
for Monster in MonsterList do
Monster.Free;
MonsterList.Clear;