Domanda

alcune domande su record in Delphi:

  1. Come record sono quasi come le classi, perché non utilizzare solo le classi al posto di record?
  2. In teoria, la memoria viene allocata per un record quando esso è dichiarato da una variabile; ma, e come viene rilasciato dopo la memoria?
  3. posso capire l'utilità di puntatori a record in un oggetto di lista, ma con Generics Container (TList<T>), ci sono necessità di utilizzare il puntatore ancora? in caso contrario, come eliminare / rilasciare ogni record in un contenitore generico? Se voglio eliminare un record specifico in un contenitore generico, come fare?
È stato utile?

Soluzione

Per 1 e 2: record sono tipi di valore, mentre le classi sono tipi di riferimento. Sono allocate sullo stack, o direttamente nello spazio di memoria di qualsiasi variabile più grande che li contiene, anziché tramite un puntatore, e puliti automaticamente dal compilatore quando escono dall'ambito.

Per quanto riguarda la terza domanda, una TList<TMyRecord> dichiara interno un array of TMyRecord per lo spazio di archiviazione. Tutti i record sono in essa saranno ripuliti quando la lista è distrutto. Se si desidera eliminare una specifica, utilizzare il metodo Delete da eliminare indice o il metodo Remove per trovare ed eliminare. Ma essere consapevoli che dal momento che è un tipo di valore, tutto quello che fai sarà fare copie del disco, non copiando i riferimenti ad esso.

Altri suggerimenti

Ci sono molte differenze tra i record e le classi; e nessun "Pointer per registrare" "Class" <>. Ognuno ha i suoi pro e contro; una delle cose più importanti circa lo sviluppo del software è quello di capire questi in modo da poter più facilmente scegliere la più appropriata per una data situazione.

  1. Questa domanda si basa su una falsa premessa. Record non sono quasi come le classi, nello stesso modo in cui numeri interi non sono quasi come doppie.
    • Le classi devono sempre essere istanziati in modo dinamico, mentre questa è una possibilità, ma non è un requisito per i record.
    • Le istanze delle classi (che noi chiamiamo gli oggetti) sono sempre passati in giro per riferimento, il che significa che più sezioni di codice condivideranno e agire sulla stessa istanza. Questa è una cosa importante da ricordare, perché si può involontariamente modificare un oggetto come un effetto collaterale; anche se una volta fatto intenzionalmente è una caratteristica potente. Record d'altra parte sono passati per valore; è necessario indicare in modo esplicito se li stai passaggio per riferimento.
    • classi non 'copia facilmente come record'. Quando dico copia, voglio dire un'istanza separata duplicazione di una fonte. (Questo dovrebbe essere ovvio alla luce del commento valore / riferimento di cui sopra).
    • Dati storici tendono a lavorare molto bene con i file tipizzati (perché sono così facili da copiare).
    • Records può sovrapporre campi con altri campi (caso x di / sindacati)
    • Questi erano i commenti su alcuni vantaggi situazionali di record; Al contrario, ci sono anche vantaggi situazionali per le classi che non ti approfondire.
  2. Forse il modo più semplice per capire questo è quello di essere un po 'pedanti su di esso. Chiariamo; la memoria non è realmente allocata 'quando la sua dichiarata', è allocato quando la variabile è di portata, e rilascia quando va fuori di portata. Così, per una variabile locale, è allocato poco prima dell'inizio della routine, e rilascia subito dopo la fine. Per un campo di classe, è allocata quando viene creato l'oggetto, e rilascia quando viene distrutta.
  3. Anche in questo caso, ci sono pro e contro ...
    • Può essere più lenta e richiedono più memoria per copiare interi dischi (come con i generici) che al solo copiare i riferimenti.
    • Passando record intorno per riferimento (utilizzando i puntatori) è una tecnica potente per cui si può facilmente avere qualcos'altro modificare la propria copia del record. Senza questo, sarebbe necessario passare il record per valore (cioè copiarlo) ricevono il record modificato di conseguenza, copiarlo di nuovo alle proprie strutture.
  4. sono puntatori ai record come le classi? No, per niente. Solo due delle differenze:
    • Corsi supportano l'ereditarietà polimorfico.
    • Le classi possono implementare interfacce.

Uno dei principali vantaggi di record è, quando si dispone di una grande "serie di record". Questo è stato creato in memoria allocando lo spazio per tutti i record in uno spazio di RAM contigua, che è estremamente veloce. Se si fosse usato "vettore di TClass", invece, ciascun oggetto nell'array dovrebbe essere assegnato per sé, che è lento.

C'è stato un sacco di lavoro per migliorare la velocità di allocazione della memoria, al fine di migliorare la velocità di stringhe e oggetti, ma non sarà mai veloce come sostituzione di 100.000 allocazioni di memoria con l'allocazione 1 di memoria.

Tuttavia, se si utilizza serie di cronaca, non copiare il record intorno a variabili locali. Che può facilmente uccidere il vantaggio di velocità.

Ci sono alcune altre differenze tra una classe e un record. Le classi possono utilizzare polimorfismo , ed esporre interfacce. Record non possono implementare i distruttori (anche se da quando Delphi 2006 possono ora implementare costruttori e metodi).

Le registrazioni sono molto utili nella segmentazione memoria in una struttura più logica dal primo elemento di dati nel record è allo stesso punto indirizzo del puntatore al disco stesso. Questo non è il caso per le classi.

1) Per permettere ereditarietà e polimorfismo, le classi hanno un certo overhead. Records non permettono loro, e in alcune situazioni possono essere un po 'più veloce e semplice da usare. A differenza di classi, che sono sempre allocati nel mucchio e gestiti attraverso riferimenti, registrazioni possono essere allocati sullo stack inoltre, accedere direttamente, e assegnati reciprocamente senza richiedere di chiamare un metodo "Assign". Anche i record sono utili per accedere ai blocchi di memoria con una data struttura, perché il loro layout di memoria è esattamente come la si definisce. Un layout memoria di istanza classe è controllato dal compilatore e contiene dati aggiuntivi per rendere oggetti lavoro (cioè il puntatore alla tabella metodo virtuale).

2) A meno che non si assegnano i record in modo dinamico, utilizzando il nuovo () o GetMem (), la memoria del record è gestita dal compilatore come ordinali, galleggianti o le matrici statiche: le variabili globali di memoria è allocato all'avvio e rilasciato quando il programma termina, e variabili locali sono allocate sullo stack inserendo un / procedura / metodo della funzione e rilasciati uscire. L'allocazione / memoria rilasciando nello stack è più veloce perché non richiede chiamate al gestore di memoria, è solo pochissime istruzioni assembler di modificare i registri di stack. Ma essere consapevoli che l'attribuzione grande struttura in pila può causare un overflow di stack, perché la dimensione massima dello stack è fisso e non molto grande (vedi opzioni linker). Se i record sono i campi di una classe, vengono assegnati quando viene creata la classe e rilasciati quando la classe viene liberato.

3) Uno dei vantaggi di farmaci generici è quello di eliminare la necessità di una gestione puntatore a basso livello -. Ma essere consapevoli del funzionamento interno

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top