2009-05-09 15 views
15

Delphi 2006 ha introdotto nuove funzionalità per i record, rendendoli più "orientati agli oggetti".Quando dovrei usare tipi di record avanzati in Delphi invece di classi?

In quali situazioni è il tipo di record più appropriato per un progetto rispetto a un tipo di classe? Quale vantaggio deve utilizzare questi tipi di record?

+0

Si può dare un'occhiata al [nostro Array involucro dinamico] (http://blog.synopse.info/post/2011/03/12/TDynArray-and-Record-compare/load/save-using -fast-RTTI), che aggiunge metodi simili a TList per qualsiasi array dinamico. È anche in grado di serializzare il contenuto dell'array/record. Ho anche scoperto un errore casuale in Delphi 2010 (almeno), sugli oggetti: a volte, [gli oggetti conteggio di riferimento non sono stati inizializzati] (http://blog.synopse.info/post/2011/01/29/record-and -oggetto-problema-in-Delphi-2010)! In questo caso, devi usare i record per tali strutture. –

risposta

15

Hai record, oggetti e classi.

I record sono disponibili dal turbo pascal 1.Sono leggeri, in grado di avere proprietà e metodi, ma non supportano l'ereditarietà. Ci sono alcuni problemi con le funzioni che restituiscono i record. Se questi record hanno metodi questo a volte dà errori interni:

type 
    TRec = record 
    function Method1: Integer; 
    end; 

function Func: TRec; 


procedure Test; 
var 
    x : TRec; 

begin 
    Func.Method1; // Sometimes crashes the compiler 
    // Circumvention: 
    x := Func; 
    x.Method1; // Works 
end; 

Gli oggetti sono introdotti con turbo pascal 5 se sono corretto. Hanno quindi fornito un modo per OO con pascal. Sono più o meno deprecati con l'introduzione di Delphi, ma puoi ancora usarli. Gli oggetti possono implementare interfacce.

Le classi sono introdotte con Delphi 1 e la più versatile. Implementano interfacce e supportano l'ereditarietà. Ma ogni variabile di classe è un puntatore nascosto. Ciò significa che le classi devono essere create nell'heap. Fortunatamente questo processo è in gran parte nascosto.

Di seguito è riportata una tabella con le differenze tra i tre. Ho aggiunto l'interfaccia per il completamento.

    |Class|Object|Record|Interface| 
------------------|-----------------------------| 
Are pointers?  | y | n | n | y | 
Inheritance  | y | y | n | y | 
Helpers   | y | n | y | n | 
Impl. Interface | y | y | n | - | 
Visibility  | y | y | n | n | 
Method   | y | y | y | y | 
Fields   | y | y | y | n | 
Properties  | y | y | y | y | 
Consts   | y | y | y | n | 
Types    | y | y | y | n | 
Variants   | n | n | y | n | 
Virtual   | y | n | y | - | 
------------------|-----------------------------| 
+0

Potresti dire se gli oggetti sono ancora supportato in Delphi? Conosco la "procedura xx dell'oggetto"; ma non ricordo di averli visti da nessun'altra parte. –

+0

Sì gli oggetti sono ancora supportati in D2009. Non ci sono helper di oggetti, ma gli oggetti possono implementare interfacce. –

+1

E il contrato "procedura xx di oggetto" serve per dichiarare le firme degli eventi per i metodi, AFAIK non ha nulla a che fare con gli oggetti. –

1

È possibile utilizzare operator overloading (come le conversioni implicite). Puoi farlo su Delphi 2007+ o 2006.NET anche sugli oggetti, ma solo su questi dischi su Win32 2006.

8

penso che queste funzioni erano disponibili anche in Delphi 8 e 2005.

linea guida principale: se siete in dubbio, utilizzare una classe.

Per il resto è necessario comprendere la differenza principale: gli oggetti di classe vengono sempre utilizzati tramite un riferimento e vengono creati chiamando un Costruttore.

La gestione della memoria e l'allocazione per i record sono gli stessi dei tipi di base (cioè intero, doppio). Ciò significa che vengono passati ai metodi in base al valore (a meno che non venga utilizzato var). Inoltre non è necessario registrare gratuitamente, ed è questo il motivo per cui supportano l'overloading dell'operatore. Ma nessuna eredità o metodi virtuali ecc. I nuovi record possono avere un costruttore ma il suo uso è un po 'facoltativo.

Le aree principali ed i criteri per l'utilizzo di record:

  • quando si tratta con le strutture dalla API Win32

  • quando i tipi non hanno identità (perché assegnazione significa copia)

  • quando le istanze non sono troppo grandi (la copia di grandi record diventa costosa)

  • w gallina che costruisce tipi di valore, il cui comportamento dovrebbe imitare i tipi numerici. Gli esempi sono DateTime, Numeri complessi, Vettori, ecc. E poi l'overloading dell'operatore è una caratteristica piacevole, ma non renderlo il fattore decisivo.

e l'efficienza-saggio, non esagerare con questo:

  • per i tipi più piccoli che si mettono in array spesso.

Infine, le regole per l'utilizzo di una classe o di un record non sono state realmente modificate dalle precedenti versioni di Delphi.

+0

Sono disponibili per la piattaforma Delphi.NET, ma non per win32 Delphi fino al 2007. – DiGi

+0

mjustin non era specifico su quali caratteristiche, ma proprietà, metodi e pubblico/privato erano in giro per D2005/win32 –

6

In aggiunta alle altre risposte (sovraccarico dell'operatore, tipi di valore leggero), è consigliabile creare i record degli enumeratori anziché le classi. Dal momento che sono allocati nello stack, non c'è bisogno di costruirli e distruggerli, il che rimuove anche la necessità del tentativo nascosto..finalmente blocco che il compilatore pone attorno agli enumeratori di classe.

Vedere http://hallvards.blogspot.com/2007/10/more-fun-with-enumerators.html per ulteriori informazioni.

Problemi correlati