Quando dovrei usare i tipi di record avanzati in Delphi anziché nelle classi?
-
20-08-2019 - |
Domanda
Delphi 2006 ha introdotto nuove funzionalità per i record, rendendole più orientate agli oggetti '.
In quali situazioni il tipo di record è più appropriato per un progetto rispetto a un tipo di classe? Quale vantaggio ha usare questi tipi di record?
Soluzione
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à. Vi sono alcuni problemi con le funzioni che restituiscono i record. Se questi record hanno dei metodi, questo a volte genera 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 vengono introdotti con turbo pascal 5 se ho ragione. Hanno quindi fornito un modo per OO con pascal. Sono più o meno deprecati con l'introduzione di Delphi, ma puoi comunque usarli. Gli oggetti possono implementare interfacce.
Le classi sono introdotte con Delphi 1 e le più versatili. Implementano interfacce e supportano l'ereditarietà. Ma ogni variabile di classe è un puntatore nascosto. Ciò significa che è necessario creare le classi nell'heap. Fortunatamente questo processo è per lo più 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 | - |
------------------|-----------------------------|
Altri suggerimenti
Penso che quelle funzionalità fossero disponibili anche in Delphi 8 e 2005.
Linee guida principali: in caso di dubbi, utilizzare una classe.
Per il resto devi capire la differenza principale: gli oggetti di classe sono sempre usati attraverso un riferimento e sono creati chiamando un costruttore.
La gestione e l'allocazione della memoria per Records è la stessa 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 è per questo che supportano il sovraccarico dell'operatore. Ma nessuna eredità o metodi virtuali ecc. I nuovi Record possono avere un costruttore ma il suo uso è un po 'facoltativo.
Le principali aree e criteri per l'utilizzo dei record:
-
quando si tratta di strutture dall'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)
-
quando si creano tipi di valore, il cui comportamento dovrebbe imitare i tipi numerici. Esempi sono DateTime, numeri complessi, vettori, ecc. E quindi il sovraccarico dell'operatore è una bella caratteristica, ma non è questo il fattore decisivo.
E dal punto di vista dell'efficienza, non esagerare:
- per tipi più piccoli che metti spesso in array.
E infine, le regole per l'utilizzo di una classe o di un record non sono state realmente modificate rispetto alle versioni precedenti di Delphi.
Oltre alle altre risposte (sovraccarico dell'operatore, tipi di valore leggero), è una buona idea registrare i record degli enumeratori anziché le classi. Dato che sono allocati nello stack, non è necessario costruirli e distruggerli, il che rimuove anche la necessità del tentativo nascosto ... blocca definitivamente che il compilatore posiziona attorno agli enumeratori di tipo di classe.
Vedi http://hallvards.blogspot.com/ 2007/10 / more-fun-with-enumerators.html per ulteriori informazioni.
Puoi utilizzare sovraccarico dell'operatore (come conversioni implicite). Questo è possibile su Delphi 2007+ o 2006.NET anche su oggetti, ma solo su questi record su win32 del 2006.