Beim Portieren von Code von C ++ nach Delphi müssen Sie sehr häufig den CODE mit STL -Sammlungen anstellen. Die von Delphi angebotene Sammlung ist sehr asketisch und daher manchmal manchmal
Es ist schwierig, einen geeigneten Ersatz zu finden. Manchmal stoßen Sie auf den Code, in dem das Objekt in den Stapel platziert wird, oder verwendet seinen eigenen Speicher Allocator.
Ich mag den vorgeschlagenen Daten -Aktualisierungsmodus wirklich nicht. Um die Daten zu aktualisieren, muss ich den darin enthaltenen Wert aus der Sammlung abrufen, den Wert aktualisieren und dann den geänderten Wert zurücksetzen. Dies erfordert mindestens zwei zusätzliche Kopiervorgänge. Wir können ein Datenelement nicht als VAR -Parameter an eine Prozedur übergeben.
Es gibt keine Möglichkeit, dass eine Sammlung die Art und Weise verändert, wie das Speicher zugewiesen wird. Der Speicher für Objekte und Aufzeichnungen wird von einem gemeinsam genutzten Heap zugewiesen. Nach dem Gebrauch muss der Speicher sorgfältig auf den Haufen zurückgegeben werden. Das korrekte Befreiung des Speichers ist nicht immer eine triviale Aufgabe, und es braucht sowohl die Prozessorzeit als auch die Zeit des Programmierers, um diesen Code zu schreiben. In STL können Sie Ihren eigenen Speicher Allocator für alle Arten von Sammlungen angeben.
Diese Implementierung stützt sich auf Aufzeichnungen und Zeiger. Bisher sehe ich keine Möglichkeit, das zu implementieren, was ich mit Standardobjekten verwenden möchte. Die Schöpfung und Zerstörung von Objekten verwendet einen gemeinsam genutzten Speicherhaufen. Es gibt keine Möglichkeit, Objekte auf den Anrufstapel zu platzieren. Das gute alte "Objekt" wird deklariert und es wird nicht unterstützt, neue Funktionen für diesen Typ hinzuzufügen.
Diese Sammlungsimplementierung basiert auf der Mechanismus -Speicherverwaltung basierend auf typisierten Speicherregionen. Die Verwendung typisierter Speicherregionen ermöglicht es, die Lösung einer Reihe von Aufgaben zu vereinfachen:
Die Aufgabe, Speicher zu befreien, wird einfacher und kann viel schneller erfolgen.
Es ist eine bekannte Tatsache, dass ein Standard-Speichermanager thread-sicher sein muss. Nur ein Thread kann zu einem bestimmten Zeitpunkt auf den Speichermanager zugreifen. Die Zuordnung und Freigabe des Gedächtnisses verwendet gegenseitige Ausschlussmechanismen und ist keine schnelle Operation, insbesondere wenn der Speicher stark defragmentiert ist. Bei Verwendung eines separaten typisierten Speicherbereichs verweisen wir nur zum Zeitpunkt der Erhöhung des erforderlichen Speichers und des Löschens der Struktur nach seiner Verwendung auf den Standard -Speichermanager.
Unterstützung für grundlegende Strukturen mit der Fähigkeit, einen Speicher Allocator anzugeben. Die Elemente der Liste werden über Zeiger zugegriffen. In der Regel befindet sich der Speicher für Werte im sogenannten segmentierten Speicherbereich, der während des Betriebs nicht bewegt wird. Wenn es notwendig ist, das Gedächtnis eines Bereichs zu erhöhen, wird ein zusätzliches Speichersegment dafür zugewiesen. Dies bedeutet, dass wir über einen Zeiger auf Datenelemente in einer solchen Region zugreifen können.
Für Arrays verwenden wir den sogenannten zusammenhängenden Speicherbereich. Datenelemente werden über einen Index zugegriffen. Erhöhen Sie bei Bedarf den Speicher der Region, ein Segment mit einer großen Größe wird dafür zugewiesen und Daten aus dem aktuellen Speichersegment in das neue Segment kopiert. Nach dem Kopieren der Daten wird das alte Segment gelöscht.
Letztendlich ist das Durcharbeiten durch Zeiger sehr bequem und effizient. Der Code wird viel einfacher und prägnanter. Wenn Sie jedoch keine Erfahrung mit Zeigern haben, ist es einfach, sich in den Fuß zu schießen. Für Lüfter der Kapselung können Sie die gewünschte Struktur als privates Feld zusammenfassen. Als nächstes öffnen wir nur den erforderlichen Teil der Schnittstelle, indem wir die erforderlichen Methoden und Eigenschaften im öffentlichen Abschnitt überschreiben. Wenn wir die Inline -Option einsetzen, vermeiden wir zusätzliche Kosten. Der Delphi -Compiler generiert keinen Code für überschriebene Methoden. An der Stelle des Methodenaufrufs wird die Aggregatstrukturmethode direkt aufgerufen.
TsgTuple<T1, ...> generische TupelTsgArray<T> Generisches Array mit Speicherzuweisung aus einem gemeinsamen SpeicherbereichTsgList<T> Generische WertelisteTsgRecordList<T> Generische Liste von Werten, die vom Zeiger zugegriffen werdenTsgLinkedList<T> Generische bidirektionale verlinkte ListeTsgForwardList<T> generische, unidirektionale verlinkte ListeTsgHashMap<Key, T> generisches ungeordnetes WörterbuchTsgMap<Key, T> generisch geordnetes Wörterbuch basierend auf 2-3 BaumTsgSet<Key> Generikumsatz basierend auf 2-3 BäumenTsgPointerArray Untyped Liste von ZeigernTsgPointerList Untyped -Liste der vom Zeiger zugegriffenen WerteTCustomLinkedList Untyped Bidirectional Linked ListTsgCustomTree Untyped Dictionary basierend auf 2-3 Bäumen Wir haben angefangen, Delphi -Iteratoren hinzuzufügen. Jetzt können wir die Konstruktion for p in List do; Das Interessanteste ist, dass wir Datensatz verwenden, um den Iterator zu implementieren und es funktioniert! Im Vergleich zur Verwendung von Objekten ist der generierte Code viel effizienter, und die Variable für den Iterator befindet sich auf dem Stapel. Dies stellte sich für mich als ziemlich angenehme Überraschung heraus!
Die Möglichkeit, einen Speicherallocator anzugeben, bedeutet auch, dass wir hauptsächlich mit Datensätzen arbeiten. In der Regel verwendet eine Struktur eine oder mehrere Speicherregionen, die ein einfacher Speichermanager sind. Nachdem wir die Struktur verwendet haben, haben wir die Möglichkeit, den gesamten Gedächtnis zurückzugeben, der durch die Befreiung des Speicherbereichs besetzt ist. Wir haben Einschränkungen bei der Vererbung. In einigen Fällen können wir die Vererbung durch Aggregation und Helfer ersetzen. In der Regel für die Implementierung von Sammlungen ist dies kein Problem. Durch die Verwendung von Datensätzen können Sammlungen gestapelt werden. Dies ist manchmal sehr bequem.
Mit einem Objektpool können Sie die Wiederverwendung von Strukturen beim Erstellen von Objekten verwalten, ist Speicherintensiv oder wenn eine begrenzte Anzahl von Objekten eines bestimmten Typs erstellt werden kann.
Wenn wir aufhören, etwas zu verwenden, lohnt es sich nicht immer, die Struktur oder das Objekt zu löschen. Oft muss das Objekt neu erstellt werden.