Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class Delphi类TList_Class_Delphi_Generics_Foreach - Fatal编程技术网

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。但该内部数组的内容对您来说并不重要for Monster in MonsterList do Monster.Free; MonsterList.Clear;