Frage

einige Fragen zu Datensätzen in Delphi:

  1. Wie Aufzeichnungen fast wie Klassen sind, verwenden, warum nicht nur Klassen statt Aufzeichnungen?
  2. In der Theorie wird der Speicher für einen Datensatz zugeordnet, wenn sie durch eine Variable deklariert wird; aber, und wie wird der Speicher freigegeben, nachdem?
  3. kann ich die Nützlichkeit von Zeigern auf Datensätze in einer Liste Objekt verstehen, aber mit Generics Container (TList<T>) gibt es müssen noch Zeiger benutzen? wenn nicht, wie löschen / freigeben jeden Datensatz in einen generischen Container? Wenn ich einen bestimmten Datensatz in einen generischen Container will löschen, wie es zu tun?
War es hilfreich?

Lösung

Für 1 und 2: Aufzeichnungen sind Werttypen, während Klassen Referenztypen sind. Sie sind auf dem Stapel reserviert oder direkt im Speicherraum eines größeren Variable, die sie enthält, statt über einen Zeiger, und vom Compiler automatisch gereinigt, wenn sie sich außerhalb des Geltungsbereichs gehen.

Wie für Ihre dritte Frage, ein TList<TMyRecord> intern deklariert einen array of TMyRecord für Stauraum. Alle Datensätze in es wird aufgeräumt werden, wenn die Liste zerstört wird. Wenn Sie eine spezifische löschen möchten, verwenden Sie die Delete Methode durch den Index zu löschen, oder die Remove Methode zu finden und zu löschen. Aber beachten Sie, dass, da es ein Werttyp ist, alles, was Sie tun, werden die Kopien des Datensatzes werden machen, nicht das Kopieren Verweise auf sie.

Andere Tipps

Es gibt viele Unterschiede zwischen den Datensätzen und Klassen; und kein "Pointer aufnehmen" <> "Class". Jeder hat seine eigenen Vor-und Nachteile; eine der wichtigsten Dinge über Software-Entwicklung ist es, diese zu verstehen, damit Sie leichter die am besten geeignete für eine gegebene Situation wählen können.

  1. Diese Frage auf einer falschen Prämisse beruht. Aufzeichnungen sind nicht fast wie Klassen, in der gleichen Weise, ganze Zahlen nicht fast wie Doubles sind.
    • Klassen müssen immer dynamisch instanziert werden, während dies eine Möglichkeit, aber keine Voraussetzung für die Aufzeichnungen.
    • Instanzen von Klassen (die wir Objekte nennen) immer um als Referenz übergeben, was bedeutet, dass mehrere Codeabschnitte teilen werden und auf derselben Instanz handeln. Das ist etwas, wichtig zu erinnern, weil Sie versehentlich ein Objekt als Nebeneffekt ändern können; obwohl, wenn es eine leistungsstarke Funktion absichtlich getan. Aufzeichnungen auf der anderen Seite werden von Wert übergeben; Sie müssen explizit angeben, ob sie durch Bezugnahme vorbei sind.
    • Klassen nicht ‚Kopie so einfach wie Aufzeichnungen‘. Wenn ich Kopie sage, meine ich eine separate Instanz eine Quelle zu duplizieren. (Dies sollte im Lichte der Wert / Referenz Kommentar über offensichtlich sein).
    • Datensätze sind in der Regel sehr gut mit typisierten Dateien arbeiten (weil sie so einfach zu kopieren ist).
    • Datensätze können Felder überlagern mit anderen Bereichen (Fall x von / Gewerkschaften)
    • Diese
    • waren Kommentare zu bestimmten situativen Vorteilen von Aufzeichnungen; Umgekehrt gibt es auch situative Vorteile für Klassen, die ich nicht ausarbeiten würde.
  2. Vielleicht ist der einfachste Weg, dies zu verstehen, ist ein wenig pedantisch darüber sein. Lassen Sie uns klären; Speicher ist nicht wirklich zugeordnet ‚wenn ihr erklärtes‘ zugeordnet ist, wenn die Variable im Gültigkeitsbereich befindet, und freigegeben, wenn es den Bereich verlässt. Also für eine lokale Variable, es ist kurz vor dem Start der Routine zugeordnet und freigegeben kurz nach dem Ende. Für eine Klasse Feld, wird es zugeordnet wird, wenn das Objekt erstellt wird, und freigegeben, wenn es zerstört wird.
  3. Auch hier gibt es Vor-und Nachteile ...
    • Es kann langsamer sein und mehr Speicher benötigen ganze Datensätze zu kopieren (wie bei Generika), als nur die Referenzen zu kopieren.
    • Aufzeichnungen um Übergabe als Referenz (mit Zeigern) ist eine leistungsfähige Technik, bei der man leicht etwas sonst kann Ihre Kopie des Datensatzes ändern. Ohne diese würden Sie Ihren Eintrag, der von Wert (das heißt kopieren) erhalten den geänderten Datensatz als Ergebnis, kopieren Sie sie wieder auf Ihre eigenen Strukturen übergeben.
  4. Sind Zeiger auf Datensätze wie Klassen? Nein überhaupt nicht. Nur zwei der Unterschiede:
    • Klassen unterstützen polymorphe Vererbung.
    • Klassen können Schnittstellen implementieren.

Einer der wichtigsten Vorteile von Datensätzen ist, wenn Sie eine große „Array von record“ haben. Dies wird im Speicher erzeugt durch Raum Zuteilung für alle Datensätze in einem zusammenhängenden RAM-Speicher, der extrem schnell. Wenn Sie „Array von TClass“ stattdessen verwendet hatten, jedes Objekt im Array würde von selbst zugewiesen werden, was langsam ist.

Es hat eine Menge Arbeit, die Geschwindigkeit der Zuweisung von Speichern, zu verbessern, um die Geschwindigkeit von Strings und Objekten zu verbessern, aber es wird nie mit 1 Speicherzuweisung als Ersatz für 100.000 Speicherzuordnungen so schnell sein.

Wenn Sie jedoch Array von Datensatz verwenden, kopieren Sie nicht den Rekord um in lokalen Variablen. Das kann die Geschwindigkeit Vorteil leicht töten.

Es gibt ein paar anderen Unterschiede zwischen einer Klasse und einem Rekord. Klassen können verwendet werden Polymorphismus und Schnittstellen aus. Datensätze können nicht Destruktoren implementieren (obwohl seit Delphi 2006 sie jetzt Konstrukteure und Methoden implementieren können).

Datensätze sind sehr nützlich Speicher in eine logische Struktur in segmentieren, da das erste Datenelement in der Aufzeichnung an derselben Adresse Punkt des Zeigers auf den Datensatz selbst. Dies ist nicht der Fall für die Klassen.

1) zu ermöglichen, für die Vererbung und Polymorphismus, Klassen gewissen Overhead haben. Aufzeichnungen erlauben sie nicht, und in einigen Situationen können etwas schneller sein und einfacher zu bedienen. Im Gegensatz zu Klassen, die in dem Heap und verwaltet durch Referenzen immer zugeordnet sind, können Datensätze auf dem Stapel auch zugegriffen werden, zugeordnet direkt und einander zugeordnet, ohne dass ein „Assign“ Methode aufzurufen. Auch Aufzeichnungen sind nützlich Speicherblocks mit einer bestimmten Struktur zugreifen zu können, weil ihr Gedächtnis Layout genau ist, wie Sie es definieren. Eine Klasseninstanz Speicherlayout wird vom Compiler gesteuert und zusätzliche Daten hat, um Objekte (das heißt der Zeiger auf die Tabelle virtueller Methoden) funktioniert.

2) Es sei denn, Sie Datensätze dynamisch zuweisen, mit New () oder GetMem (), Rekord-Speicher wird vom Compiler als ordinals verwaltet, Schwimmern oder statische Arrays: globale Variablenspeicher beim Start zugewiesen und freigegeben wird, wenn das Programm beendet wird, und lokale Variablen werden auf dem Stapel zugeordnet, eine Funktion / Verfahren / Eingabe-Verfahren und freigegeben austritt. Zuteilen / Freigabe-Speicher in dem Stapel ist schneller, weil sie an den Speicher-Manager keine Anrufe erfordern, ist es nur sehr wenige Assembler Anweisungen, um die Stack-Register zu ändern. Aber beachten Sie, dass auf dem Stapel große Struktur Zuweisung verursachen kann einen Stapelüberlauf, da die maximale Stapelgröße festgelegt ist und nicht sehr groß (Linker-Optionen sehen). Wenn Datensätze Felder einer Klasse sind, sie zugeordnet sind, wenn die Klasse erstellt und freigegeben wird, wenn die Klasse freigegeben wird.

3) Einer der Vorteile von Generika ist die Notwendigkeit von Low-Level-Management-Zeiger zu beseitigen -. Aber das Innenleben bewusst sein,

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top