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