Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von mulcheo »

okay okay, das wird vielleicht etwas länger, aber ich brauche einen educated guess, ob es sich lohnt, meine Progrsturktur umzustellen...

was mein project grob macht:
ich habe einen Text, in dem ich gewisse Strukturen markieren, speichern und letztlich statistisch auswerten will. Hauptsächlich geht es da um Grammatik. Ich erstelle also u.a. Objekte bzw. dynamische arrays, die bespielsweise speichern: in Zeile 4532 leitet Komma 3 einen Nebensatz vom Typ 6 ein, der bei Komma 5 endet - so ungefähr, nur eben als Code und für alle möglichen Strukturen, nicht nur Nebensätze ...

wo ich Probleme sehe:
ich arbeite teilweise mit pointern, insbesondere dann, wenn es darum geht Strukturen, die gerade auf dem Bildschirm sind, mit denen meiner 'Datenbank' zu linken (etwa nach der Idee: Wort 3 in Zeile 6 auf dem Bildschirm entspricht Wort 23 im Satz xyz). Für das Speichern löse ich aber immer sämtliche pointer in absolute Werte auf, damit ich ein record in eine typisierte Datei speichern kann. Das ist natürlich super umständlich und fällt mir insbesondere auf die Füße, wenn ich Objekte lösche. zur Erklärung: wenn ich bespielsweise Satz 2000 lösche, aber sämtliche Einträge wie oben beschrieben gespeichert sind, muss ich nun alle 'Datenbanken' durchlaufen, und alle Verweise die auf Satz 2001 aufwärts zeigen, neu buchen, indem ich dort einen integerwert decrease etc. etc.

wo ich Hilfe brauche:
ich bin nun auf die Möglichkeit gestoßen, TObjectlist zu nutzen. Das würde, wenn ich es richtig sehe, beim Löschen, Verschieben etc. einiges vereinfachen. Das ist ein erster Anstoß, was mich aber wirklich umtreibt und mich vermutlich auch dazu bewegen würde, meine knapp 4000 Zeilen Programmcode umszustülpen, ist die Idee pointer zu speichern. Ich habe nur keine Anhung, ob das überhaupt geht. Nach meinem Verständnis ist im Pointer ja nur die speicheradresse hinterlegt. Leider kann ich auch garnicht konkreter Fragen, weil mir das Wissen fehlt, das Problem genauer zu fassen. Also das wäre ein erster Schritt: kann ich pointer so speichern, dass nach dem Laden wieder auf das richtige Object verwiesen wird (das seinerseits aus einer anderen Liste geladen wird)?

zur Veranschaulichung etwas Democode:

Code: Alles auswählen

PTDBWort = ^TDBWort;

(...)

TDBWort = class
  Text: string;
  Orig: TOrig;  // TOrig ist ein record, das diverse integer-Werte beinhaltet
  Verweis: PTWort;
  ZuMarker: PTDBMarker;

  procedure GetMarker;
  function  GetPos: integer;
end;           

(...)

TPartizip = class
  private
    procedure Assign(Quelle: TPartizip);
 
  public
    Wort: array of PTDBWort;  
    [...]       
end;
          
TSyntax = class
  Part: array of TPartizip;
  [...]
  procedure Laden;
  procedure Speichern;

  Constructor Create;
  Destructor Destroy; override;
end;                             
das ist zunächst einmal ein winziger Auszug... aber darum geht es ungefähr: ich habe eine Klasse TSyntax, in der u.a. alle Partizipien hinterlegt sind. Jedes Partizip ist ein Objekt der Klasse TPartizip und hat u.a. über einen Pointer hinterlegt, welche Wörter zu ihm gehören. Das realisiere ich zur Laufzeit über den Pointer 'Wort: array of PTDBWort; ', der auf ein Objekt aus der Klasse 'Datenbank Wort' (TDBWort) weist. Jedes Objekt aus TDBWort wiederum hat unter TOrig gespeichert, wo genau es im Ausgangstext steht (das sind integerWerte für Zeile, Element etc.).
Wenn ich nun Partizipien speicher, löse ich den Pointer 'Wort: array of PTDBWort' in seine integerWerte auf und lege sie in einer typisierten file ab. beim laden lese ich diese Werte ein und schaue dann via CompareMem, welche Objekte aus TDBWort die gleichen integers für Zeile und Element aufweisen - bei einem match setze ich dann einen neuen pointer.

kann ich diese ganzen Zwischenschritte sparen, wenn ich irgendwie pointer speichern kann? Ist es dafür notwenig, alle Daten in einer einzelnen Datei zu speichern und ist evtl. TObjectList ein Teil der Lösung?

Liebe Grüße!

Benutzeravatar
theo
Beiträge: 10867
Registriert: Mo 11. Sep 2006, 19:01

Re: Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von theo »

Verstehe fast nur Bahnhof, aber soviel: TObjectList ist nichts "Magisches", nur eine TList für TObjects. Dazu hat sie noch OwnsObjects für die ggf. interne Freigabe der Objekte.
Das ist zwar praktisch, aber kein "Quantensprung".

Pointer speichern ist keine gute Idee. Man müsste die Objekte/Records mit IDs versehen oder über einen Listenindex identifizieren.

Da ich nicht genau weiss wo du hin willst, hier noch einen Hinweis: http://tiopf.sourceforge.net/
Das ist aber vermutlich weit über's Ziel hinaus geschossen und ich kenne mich damit nicht aus.

Es folgen sicher noch bessere Antworten als diese, aber einer muss ja mal beginnen. :wink:

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von Sieben »

Also das wäre ein erster Schritt: kann ich pointer so speichern, dass nach dem Laden wieder auf das richtige Object verwiesen wird?
Nein. Wie Theo schon schrob müsstest du auch im Falle einer TObjectList deine Objekte zum Speichern und erneuten Laden wieder 'auflösen'. TObjectList hat aus Gründen keine Methode, sich selbst zu speichern. Beim Löschen, Verschieben etc. würde sie allerdings tatsächlich vieles vereinfachen.

Ich würde aber mal darüber nachdenken, die Anführungsstriche bei 'Datenbank' zu entfernen und wirklich eine zu verwenden. Der Strukturentwurf wäre sicher nicht ganz trivial, sollte aber auch relational machbar sein, sprich in einem ganz normalen DBMS. Was vielleicht noch eine Recherche wert wäre: Objektdatenbanken. Ich habe aber keine Ahnung, ob oder was sich da in den letzten Jahren getan hat.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6768
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von af0815 »

tiOPF hat mit der Aufgabenstellung überhaupt nichts zu tun. Da geht es ums persitent machen von Daten in einer beliebigen Datenbank. Pointer sind mal keine Daten, sondern nur Zeiger auf Daten. Weil diese Zeiger von Programmlauf zu Programmlauf, von Rechner zu Rechner sich ändern macht es keinen Sinn Pointer zu speichern.
in Zeile 4532 leitet Komma 3 einen Nebensatz vom Typ 6 ein, der bei Komma 5 endet
Sowas kann man in einer DB speichern. Zeile 4532 ist eine Entfernung die immer gleich ist, solange sich die Ausgangsdaten nicht ändern. Nebensatz vom Typ 6 und bei Komma 5 endet, sind alles daten die ich sowohl in einem Record als auch einem Datensatz speichern kann.

Dabei ist auch klar, ändern sich die Ausgangsdaten, sind alle annahmen dazu nicht mehr gültig. Das kann man mit einem Hash über die Ausgangsdaten auch speichern.

Aber das ist das was sowieso schon hier
Für das Speichern löse ich aber immer sämtliche pointer in absolute Werte auf, damit ich ein record in eine typisierte Datei speichern kann.
beschrieben, das ist nichts Umständliches und Normal. Man kann Pointer die nur auf einem System zu einem Programmzeitpunkt gültig sind nicht persistent speichern.

Statt Ojektpointer zu verwenden, kann man auch entsprechende Arrays oder Collections bauen und somit die Sache vereinfachen. Arrays kann man gezielt abspeichern bzw. Collection haben das schon eingebaut, dan man die serialisieren kann. Wie gesagt, dazu muss man mal von Pointern wegkommen, egal welche Lösung du benötigst bzw. bevorzugst.

Wenn du in deinem Programm mit einer der Objektlisten arbeitest, brauchst du immer etwas um diese Objektlisten von den Objektpointern zu befreien oder wieder an neue Objektpointer zu binden. Egal wie man es dreht und wendet.

Und zum Schluss ist es egal ob due in eine typisierte Datei schreibst oder in eine Datenbank. Das ist wieder eine Designsache was für dein Projekt sinnvoller ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von mulcheo »

Danke, das gibt mir erstmal die nötige Orientierung. Leider ändern sich die Ausgangsdaten schon ab und an, was viel Aufwand bedeutet. Vermutlich ist es sinnvoll, zur Laufzeit alles über pointer und Objectlist zu klären und für jedes Laden, Speichern, und Ändern der Ausgangsdaten eine Auflösroutine zu fahren. Die Idee eines Hash ist interessant, aber da jede Änderung der Ausgangsdaten zur Laufzeit und über den User geschieht, ist auch im Grunde immer transaprent, was sich wohin verschiebt oder ändert...

Dann mach' ich mich mal an die Arbeit...

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Tobjectlist / Speichern von Objekten und Pointern - soll ich umstellen?

Beitrag von fliegermichl »

Ich würde vor dem speichern eine globale Objektliste erstellen, in die jedes Objekt reinkommt.
Beim speichern wird dann der Index des Objektes in die Datei geschrieben. Nach dem laden wird der Index wieder mit der aktuellen Adresse der Objektinstanz ersetzt.

Antworten