|
Using the TList Class |
There are several important points to remember about the TList class. Most importantly, TList manages its own memory, but does not dereference, allocate, or free memory for the item values. Although TList declares the type of an item as Pointer, you can store anything else that fits into the same amount of memory as a Pointer, such as an Integer, a small set, or an enumerated value. Just remember to use an appropriate type cast, as was shown in Listing 5-2.
If you dynamically allocate memory and store pointers to this memory in a TList, then you must remember to free all the items before freeing the TList object itself. You might find it most convenient to do this by deriving your own class from TList, as shown in Listing 5-3. Be aware that none of the methods of TList are virtual, so you must use your derived class in all type declarations or else Delphi will not call your methods, but those of TList. This inconvenience is addressed later in the chapter, in the section A Better TList Class.
type
TS_ObjectList = class(TList)
protected
function GetObject(Index: Integer): TObject;
procedure SetObject(Index: Integer; Value: TObject);
procedure SetCount(Value: Integer);
procedure SetCapacity(Value: Integer);
public
destructor Destroy; override;
procedure Clear;
procedure Delete(Index: Integer);
property Objects[Index: Integer]: TObject read GetObject write SetObject;
property Count write SetCount;
end;
{ Clear all the objects from the list and destroy the list. }
destructor TS_ObjectList.Destroy;
begin
Clear;
inherited Destroy;
end;
{ Return an object from the list. }
function TS_ObjectList.GetObject(Index: Integer): TObject;
begin
Result := TObject(Items[Index]);
end;
{ Set an object in the list. Free the old object. }
procedure SetObject(Index: Integer; Value: TObject);
begin
Objects[Index].Free;
Items[Index] := Pointer(Value);
end;
{ Clear the list by deleting all objects in it. }
procedure TS_ObjectList.Clear;
var
I: Integer;
begin
for I := 0 to Count-1 do
Objects[I].Free;
inherited Clear;
end;
{ Delete an object from the list, freeing the object }
procedure TS_ObjectList.Delete(Index: Integer);
begin
Objects[Index].Free;
inherited Delete(Index);
end;
{ If the list shrinks, free the objects that are implicitly deleted. }
procedure TS_ObjectList.SetCount(Value: Integer);
begin
while Value < Count then
Delete(Count-1);
inherited Count := Value;
end;
Copyright © 1996 Waite Group Press