Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klassen allgemein "speichern" (https://www.delphipraxis.net/149957-klassen-allgemein-speichern.html)

Codewalker 3. Apr 2010 15:19


Klassen allgemein "speichern"
 
Ich gebe zu, der Titel ist nicht gelungen, aber mir ist nichts besseres eingefallen, was das Problem treffend beschreibt.
Im Prinzip möchte ich einen String einer Klasse zuordnen und das ganze z.B. in einem Array speichern.
Delphi-Quellcode:
String    Klasse
F1         TAufgabe1
G3         TAufgabe2
H4         TAufgabe3
Ich möchte jetzt aus einer Textdatei die Kürzel auslesen und dann jeweils die zugehörige Klasse ermitteln und erstellen. Alle Klassen haben eine gemeinsame Vaterklasse (nennen wir sie TAufgabe). Wenn ich jetzt eine TAufgabe4-Klasse schreibe und das Kürzel mit der Klasse in das Array eintrage, möchte ich die Erstellungsroutine aber nicht ebenfalls anpassen müssen. Wie müsste diese Speicherung aussehen, damit ich quasi den Klassentyp merken kann und daraus ein neues entsprechendes Objekt erstellen kann?

(gar nicht so einfach zu beschreiben, ich hoffe man hat verstanden, worum es geht). :gruebel:

Edit: Okay, habe es so versucht:

TTaskAssoc = TDictionary<string, TClass>;

Davon wird ein Objekt erstellt und jede andere Klasse wird darin registriert mit Kürzel und Klassenreferenz. Problem ist jetzt das Erstellen (ich lese das Kürzel aus einer XML-Datei):
Delphi-Quellcode:
Task := TaskBase.TaskTypes.Items[Node1.Nodes[i].Attribute['Type']].Create;
Da hagelt es jetzt "[DCC Fehler] E2010 Inkompatible Typen: 'TBaseTask' und 'TObject'. Aber es wäre fast das, was ich haben will

Khabarakh 3. Apr 2010 15:38

Re: Klassen allgemein "speichern"
 
Kurz skizziert:
Delphi-Quellcode:
type
  TAufgabe = class
  public
    constructor Create; virtual; //!
  ...

  TAufgabeClass = class of TAufgabe;


TDictionary<String, TAufgabeClass> Dic;

Dic.Add('F1', TAufgabe);

Dic.['F1'].Create;
/add: Ah, auf dem richtigen Weg warst du ja schon :)

Codewalker 3. Apr 2010 15:42

Re: Klassen allgemein "speichern"
 
Ich hab oben nochmal ein wenig ergänzt.
Außerdem habe ich mir RegisterClass und GetClass angesehen, aber dann muss ich ja von TPersistent ableiten (wenn ich das richtig verstanden habe). Wäre eine mögliche Lösung, aber es muss doch auch mit TObject gehen ohne den ungenutzten Overhead von TPersistent mit einzukaufen.

Khabarakh 3. Apr 2010 15:44

Re: Klassen allgemein "speichern"
 
Zitat:

Zitat von Codewalker
Ich hab oben nochmal ein wenig ergänzt.

Dito :)

Codewalker 3. Apr 2010 16:06

Re: Klassen allgemein "speichern"
 
Danke, das "class of TAufgabe" war die Lösung. Es funktioniert genau so wie es soll.
(Habe nur nicht ganz verstanden, was es macht bzw. warum man es genau so machen muss)

Khabarakh 3. Apr 2010 16:42

Re: Klassen allgemein "speichern"
 
TAufgabe(TClass(x).Create) (mit x : TClass := TAufgabe) würde dir bereits TAufgabe zurückliefern, aber nur den Konstruktor von TObject aufrufen. Um TAufgabe.Create aufzurufen, brauchen wir TAufgabeClass(x).Create.
Das wäre einmal das statische Binden des richtigen Konstruktors. Auf die unbekannten abgeleiteten Klassen können wir aber schlecht casten, also brauchen wir ab TAufgabe einen virtuellen Konstruktor. "Create" wird dann als formalen Rückgabewert immer noch TAufgabe haben, aber eine Instanz der richtigen Klasse zurückliefern und auch den richtigen Konstruktor darauf aufgerufen haben, wenn dieser TAufgabe.Create überschrieben hat.
TAufgabeClass ist also nötig, um statisch auf den virtuellen Konstruktor TAufgabe.Create zu verweisen, der dann dynamisch den richtigen überschreibenden Konstruktor aufruft. Wäre TObject.Create bereits virtual, würde TAufgabe(x.Create) mit x : TClass genügen.

Codewalker 3. Apr 2010 19:26

Re: Klassen allgemein "speichern"
 
Okay, das musste ich in Ruhe mehrmals lesen, aber jetzt hab ich es verstanden. Nochmals danke :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz