2012-04-15 9 views
6

Mi pregunta es bastante simple. Tengo un TList (llamado queue) que contiene objetos de la clase CNotif y quiero usar el método is_alive en esos objetos.¿Cómo usar un método de un objeto almacenado en un TList?

El problema es que cuando uso queue.Items[0].is_alive(), aparece un mensaje de error que dice Error: Illegal qualifier.

también estoy confundida con la forma en que puedo crear instancias de objetos en este TList (y cómo la forma en que el compilador "sabe" que los objetos almacenados son de este tipo ...)

Lo que hago ahora es : queue.Add(CNotif.create(timer, title, text, badge)) pero no creo que se suponga que se haga de esa manera.

¡Gracias de antemano!

+4

Sólo una nota al margen. Existe una convención no escrita para nombrar los tipos con el primer carácter "T", como "TLama" es el tipo de "Lama", por lo que para su caso sería "TCNotif" ;-) – TLama

+0

¿No es C para Clases y T para tipos "básicos" (como una matriz o un registro)? – halflings

+0

No, es para todos los 'T'ypes, incluyendo clases, registros, enumeraciones etc. Digamos para todo lo que tienes en la sección' type' de tu código. – TLama

Respuesta

10

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

Esto se debe a que el compilador no tiene idea de lo que queue.items[0] es distinto de un puntero genérico (véase más adelante).

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.

Esta es exactamente la forma en que necesita hacerlo. CNotif.Create construye un nuevo objeto, y ese objeto desciende de TObject. Compila bien porque su llamada queue.Add está esperando un puntero, y una variable Delphi/FreePascal que contiene una instancia de objeto es en realidad un puntero. (Las dos lenguas ocultan la necesidad de eliminar la referencia usando MyObj^ para nosotros.)

usar algo en queue.Items, es necesario indicar al compilador que hay ahí que no sea un genérico pointer (que por supuesto no tiene un método is_alive) . Usted hace eso encasillamiento:

CNotif(queue.Items[0]).is_alive 

Nota: Hay un camino más corto para utilizar el TList.Items; Items se declara como la propiedad predeterminada para el TList, por lo que se puede omitir:

queue[0] 

es lo mismo que

queue.Items[0] 

y es mucho más fácil de escribir.

+0

¡Gran respuesta! :) Muchas gracias. – halflings

+3

Los miembros de 'TList' no son' TObject' sino puntero. – NGLN

+0

Buen punto. :) Mi error; escribió demasiado rápido y debe haber pensado 'TObjectList'. Lo corregiré. Gracias. :) –

6

A menos que estés atascado con una versión antigua de Delphi, deberías buscar genéricos.

En la unidad generics.collection hay una clase TList<T> que puede usar aquí.

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; 

No he utilizado FPC y Lazarus por un tiempo, pero en Delphi Esta es definitivamente la manera de hacerlo. Las listas de punteros sin tipo y de tipos en todo el lugar pueden convertirse en una pesadilla para mantener.

+2

+1, pero podría ser bueno mencionar desde D2010 + porque hubo varios problemas en D2009 especialmente con 'TList'. – TLama

+4

En el modo ObjFPC de fpc, la sintaxis es 'tipo TQueue = specialize TFPGList ' - pero también puede usar el modo Delphi que tiene sintaxis Delphi (al menos desde 2.6). – lukstafi

Cuestiones relacionadas