2012-04-15 14 views
6

La mia domanda è piuttosto semplice. Ho un TList (chiamato queue) contenente oggetti della classe CNotif e voglio usare il metodo is_alive su quegli oggetti.Come utilizzare un metodo di un oggetto memorizzato in un TList?

Il problema è che quando uso queue.Items[0].is_alive(), viene visualizzato un messaggio di errore che indica Error: Illegal qualifier.

Sono anche confuso con il modo in cui posso istanze di oggetti in questo TList (e come il modo in cui il compilatore "sa" che gli oggetti memorizzati sono di questo tipo ...)

quello che faccio ora è : queue.Add(CNotif.create(timer, title, text, badge)) ma non penso che dovrebbe essere fatto in questo modo.

Grazie in anticipo!

+4

Solo un sidenote. C'è una convenzione non scritta per nominare i tipi con il primo carattere 'T', come' TLama' è il tipo di 'Lama', quindi per il tuo caso sarebbe' TCNotif' ;-) – TLama

+0

Non è C per Classi e T per tipi "di base" (come un array o un record)? – halflings

+0

No, è per tutti i 'T'ypes, comprese le classi, i record, le enumerazioni ecc. Diciamo per tutto ciò che hai nella sezione' type' del tuo codice. – TLama

risposta

10

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

Questo perché il compilatore ha idea di cosa queue.items[0] è diverso da un puntatore generico (vedi sotto).

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.

Questo è esattamente il modo in cui è necessario farlo. CNotif.Create crea un nuovo oggetto e tale oggetto discende da TObject. Compila bene perché la tua chiamata queue.Add è in attesa di un puntatore e una variabile Delphi/FreePascal contenente un'istanza dell'oggetto è in realtà un puntatore. (Entrambe le lingue nascondono la necessità di risolvere il riferimento utilizzando MyObj^ per noi.)

usare qualcosa in queue.Items, è necessario indicare al compilatore cosa c'è dentro di diverso da una generica pointer (che ovviamente non ha un metodo is_alive) . Fate quello typecasting:

CNotif(queue.Items[0]).is_alive 

Nota: C'è un modo più breve per utilizzare il TList.Items; Items è dichiarato come la proprietà predefinita per l'TList, in modo da poter omettere:

queue[0] 

è lo stesso di

queue.Items[0] 

ed è molto più facile da digitare.

+0

Ottima risposta! :) Molte grazie. – halflings

+3

I membri di 'TList' non sono' TObject' ma puntatore. – NGLN

+0

Buon punto. :) Errore mio; ha scritto troppo velocemente e deve aver pensato 'TObjectList'. Lo correggerò. Grazie. :) –

6

A meno che tu non sia bloccato con una vecchia versione di Delphi, dovresti esaminare i generici.

Nell'unità generics.collection c'è una classe TList<T> che è possibile utilizzare qui.

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; 

non ho usato FPC e Lazzaro per un po ', ma in Delphi questo è sicuramente il modo per farlo. Gli elenchi di puntatori e cast di tipi non tipografici possono diventare un incubo da mantenere.

+2

+1, ma potrebbe essere utile menzionare D2010 + perché c'erano molti problemi in D2009 specialmente con 'TList'. – TLama

+4

In modalità fcc ObjFPC, la sintassi è 'tipo TQueue = specialize TFPGList ' - ma è anche possibile utilizzare la modalità Delphi con sintassi Delphi (almeno dalla 2.6). – lukstafi