Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a method of an object stored in a TList?

My question is pretty simple. I have a TList (called queue) containing objects of class CNotif and want to use the method is_alive on those objects.

The problem is, when I use queue.Items[0].is_alive(), I get an error message saying Error: Illegal qualifier.

I'm also confused with the way I can instantiate objects in this TList (and how the way the compiler "knows" that the objects stored are of this type ...)

What I do now is: queue.Add(CNotif.create(timer, title, text, badge)) but I don't think it's supposed to be done that way.

Thank you in advance !

like image 860
halflings Avatar asked Apr 15 '12 16:04

halflings


2 Answers

The problem is, when I use queue.Items[0].is_alive(), I get an error message saying Error: Illegal qualifier.

That's because the compiler has no idea what queue.items[0] is other than a generic pointer (see below).

What I do now is: queue.Add(CNotif.create(timer, title, text, badge)) but I don't think it's supposed to be done that way.

This is exactly the way you need to do it. CNotif.Create constructs a new object, and that object descends from TObject. It compiles fine because your queue.Add call is expecting a pointer, and a Delphi/FreePascal variable containing an object instance is actually a pointer. (Both languages hide the need to dereference using MyObj^ for us.)

To use something in queue.Items, you need to tell the compiler what's in there other than a generic pointer (which of course doesn't have an is_alive method). You do that by typecasting:

CNotif(queue.Items[0]).is_alive

Note: There's a shorter way to use the TList.Items; Items is declared as the default property for the TList, so you can omit it:

queue[0] 

is the same as

queue.Items[0]

and is much easier to type.

like image 138
Ken White Avatar answered Nov 01 '22 17:11

Ken White


Unless you're stuck with an old Delphi version, you should look into generics.

In the generics.collection unit there is a TList<T> class that you could use here.

Queue:TList<CNotify>;

...
Begin
  Queue := TList<CNotify>.Create; // remember to clean it up
  Queue.Add(CNotify.Create(...));
  Queue.Add(CNotify.Create(...));

  If Queue[0].isAlive then
    Beep;
End;

I haven't used fpc and lazarus for a while, but in Delphi this is definitely the way to do this. Lists of untyped pointers and type-casts all over the place can become a nightmare to maintain.

like image 45
Wouter van Nifterick Avatar answered Nov 01 '22 18:11

Wouter van Nifterick