下面,我插入了Ray Konopka编写的代码(Coderage演示文稿的一部分)。我打算使用它,但是,我不确定如何清理(动态)多个对象。 我所有的尝试都是不完整的,并使内存泄漏。 任何想法都表示赞赏。 谢谢,
program stringlistDictionary;
{$APPTYPE CONSOLE}
uses
Classes,
SysUtils;
type
TPlayer = class
public
Name: string;
Position: string;
Hits: Integer;
AtBats: Integer;
constructor Create( Name, Position: string );
end;
constructor TPlayer.Create( Name, Position: string );
begin
inherited Create;
Self.Name := Name;
Self.Position := Position;
Hits := 0;
AtBats := 0;
end;
var
Team: TStringList;
Player, NewPlayer: TPlayer;
I: Integer;
function FindPlayer( const Name: string ): TPlayer;
var
Idx: Integer;
begin
Result := nil;
if Team.Find( Name, Idx ) then
Result := TPlayer( Team.Objects[ Idx ] );
end;
begin {== Main ==}
Writeln( 'StringList Dictionary' );
Writeln( '---------------------' );
Writeln;
Team := TStringList.Create;
try
NewPlayer := TPlayer.Create( 'Aramis Ramerez', 'Third Base' );
NewPlayer.Hits := 120;
NewPlayer.AtBats := 350;
Team.AddObject( NewPlayer.Name, NewPlayer );
NewPlayer := TPlayer.Create( 'Derrick Lee', 'First Base' );
NewPlayer.Hits := 143;
NewPlayer.AtBats := 329;
Team.AddObject( NewPlayer.Name, NewPlayer );
NewPlayer := TPlayer.Create( 'Ryan Theriot', 'Short Stop' );
NewPlayer.Hits := 87;
NewPlayer.AtBats := 203;
Team.AddObject( NewPlayer.Name, NewPlayer );
Player := FindPlayer( 'Derrick Lee' );
if Player <> nil then
Writeln( 'Player Found: ', Player.Name, ', ', Player.Position )
else
Writeln( 'Player not found.' );
Writeln;
Writeln( 'Active Roster' );
Writeln( '-------------' );
for I := 0 to Team.Count - 1 do
Writeln( TPlayer( Team.Objects[ I ] ).Name, #9,
TPlayer( Team.Objects[ I ] ).Position );
Readln;
finally
//!! Need to free the players.
Team.Free;
end;
end.
答案 0 :(得分:13)
使用Delphi 2009,TStringList构造函数有一个可选的布尔参数“OwnsObjects”。如果将其设置为true,则会自动释放对象。
否则,您可以执行以下操作:
for i := Team.Count-1 downto 0 do begin
Team.Objects.Free;
end;
Team.Free;
顺便说一句,公共领域是沮丧的。您可以使用属性,以便控制对字段的访问权限。您可以添加setter函数来验证输入。
type
TPlayer = class
private
FName : string;
FPosition : string;
FHits : Integer;
FAtBats : Integer;
public
constructor Create(const AName, APosition: string );
property Name: string read FName;
property Position: string read FPosition;
property Hits: Integer read FHits write FHits;
property AtBats: Integer read FAtBats write FAtBats;
end;
答案 1 :(得分:4)
有点明显,但仍然 - 每次要清除TStringList对象时,都不必编写'for ... Free'代码。你可以把它放到一个全局函数中。
procedure FreeObjects(sl: TStringList);
var
i: integer;
begin
for i := 0 to sl.Count - 1 do
sl.Objects[i].Free;
end;
FreeObjects(Team);
或者你可以将它放入TStringList助手。
TStringListHelper = class helper for TStringList
public
procedure FreeObjects;
end;
procedure TStringListHelper.FreeObjects;
var
i: integer;
begin
for i := 0 to Count - 1 do
Objects[i].Free;
end;
Team.FreeObjects;
答案 2 :(得分:3)
只是澄清一下关于gamecat的答案:我不知道delphi 2009,但通常Objects属性需要一个索引,而你真的不需要一个反向循环,所以:
for i := 0 to Team.Count-1 do
Team.Objects[i].Free;
Team.Free;
或:
while Team.Count > 0 do
begin
Team.Objects[0].Free;
Team.Delete(0);
end;
Team.Free;
答案 3 :(得分:2)
使用D7,我可以继承TStingList