Re: Delphi TObjectlistPosted by webmaster Guido
: can somebody help me with some issues with a TobjectList ? A TObjectList is capable of storing a list of objects (did not exist before Delphi 5). You mainly use it when you don't know how many objects will be stored in the list. These can be objects of your own design, for example of type TGameObject, but you can add also Delphi objects such as TStringList or even components. You may freely mix different types of objects, but for the following examples, let's stick with all objects of the same type. Say you want to have a list called "GameList". Because it will be used in more than one procedure, you have to declare GameList outside of any procedure. The same goes for the variable that you want for keeping a position, say "GamePos". If you plan to use these two variables only in one unit, then you can declare them in the "private" section of the form, like this: type TForm1 = class(TForm) Label1: TLabel; ... ... private { Private declarations } GameList: TObjectList; // list that contains TGameObjects GamePos: integer; // current position in the game public { Public declarations } end; (Note: if you want these two variables two be also available in other unit(s), you should declare them under "public" instead of under "private") Let's create GameList when the main form is created:
procedure TForm1.FormCreate(Sender: TObject); begin GameList := TObjectList.Create(True); end; Because you must destroy every object that you created yourself, let's destroy GameList at the end of the program, when the main form is destroyed:
procedure TForm1.FormDestroy(Sender: TObject); begin GameList.Free; // Note: the objects of the list are destroyed automatically, because // the list was created with .Create(TRUE) // If we created the list with .Create(FALSE) we would have to free // the items one by one ourselves, before freeing the list. end; Note: before Delphi 5, you had to use a TList instead of a TObjectList. You had to destroy *yourself* all the objects that you placed in the TList, before destroying the TList. A TList doesn't free its items automatically. This is how you create an object, set its properties and add it to the list: procedure TForm1.SomeProcedure; var GameObject: TGameObject; begin ... GameObject := TGameObject.Create; GameObject.Points := 0; GameObject.Name := 'Julie'; GameList.Add(GameObject); ... end; But of course, the class TGameObject must have been declared somewhere. (Note: this is a very basic declaration. In a real application, you would have your code in several sections, such as private, public and published. But don't worry for now :) ) At the beginning of the implementation section, add these lines: implementation constructor TGameObject.Create; begin inherited; // call the parent Create method // set defaults Points := 0; Name := ''; end; There is a disadvantage to TObjectList over a "fixed" array: when you write GameList[N], then you get only a
"generic" object, in other words: a value of the type TObject, not a TGameObject! For example, you are not
allowed to write the following: P := GameList[3].Points; ...because a generic TObject does not have a property "Points". So, in order to properly address an item in your list, "type casting" is required. Type casting is code that says: look at this "generic" object AS an object of the type "TypeSoAndSo", for example:
TGameObject(GameList[N])means "item number N of GameList, seen AS a TGameObject". Attention: numbering starts at 0, so the first object that you have added to the list is GameList[0], the second is GameList[1], and so on... Let's assume that you updated variable GamePos continuously during the game; it contains an integer value somewhere from 0 to maximally the "number of objects minus one". At a certain moment you need some properties of the game-object that corresponds with the current game position:
procedure TForm1.OtherProcedure; var GameObject: TGameObject; P: integer; begin GameObject := TGameObject(GameList[GamePos]); P := GameObject.Points; ... end; Replacing an object by another one, without changing anything else in the list, is very simple. For example, to replace the object at the "current gameposition" with another game-object:
procedure TForm1.ReplaceGame; var OtherGameObject: TGameObject; begin .... GameList[GamePos] := OtherGameObject; ... end; Other example: replacing the object at position Pos1 with the object at position Pos2:
GameList[Pos1] := GameList[Pos2]; Attention: in both these replace examples, the object that *originally* was in the list, before replacing it with another one, is destroyed (freed) automatically if the TObjectList's property "OwnsObjects" is True. If you use a TList instead of a TObjectList, then you must free the old object yourselve *before* replacing it, otherwise you'll have serious "memory leaks" in your application. |