Klassenfunktion, die in Delphi eine Instanz von sich selbst erzeugt

7

Können Sie eine Klassenfunktion haben, die eine Instanz einer Klasse erstellt:

%Vor%

und verwenden Sie es dann wie folgt

%Vor%

Und wenn ja, wie sieht dieser Funktionscode aus? Verwenden Sie die NewInstance-Methode von TObject und implementieren Sie jedes Mal für jede abgeleitete Klasse neu? Ist es sicherer / besser, den Konstruktor zu verwenden?

Ziel ist es, diesen Ansatz in einem Befehlsmuster zu verwenden und die Befehlsliste mit Klassentypen und einem Empfänger zu laden, z. B .:

%Vor%

Der Grund dafür ist, dass einige Befehle per Text / Skript spezifiziert werden und zur Laufzeit aufgelöst werden müssen.

    
MX4399 28.09.2011, 21:18
quelle

5 Antworten

2
  

Können Sie eine Klassenfunktion haben, die eine Instanz einer Klasse erstellt?
  Ist es sicherer / besser, den Konstruktor zu verwenden?

Konstruktor ist eine Klassenfunktion, die eine Instanz der Klasse erstellt. Stellen Sie einfach:

%Vor%

Und du bist gut zu gehen.

Mit dem virtual; -Teil können Sie denselben Konstruktor von New () für alle untergeordneten Klassen aufrufen.

    
dmajkic 29.09.2011, 00:10
quelle
12

Was Sie suchen, heißt factory pattern . Es kann in Delphi gemacht werden; So deserialisiert die VCL unter anderem Formulare. Was Sie vermissen, ist der Registrierungs- / Nachschlageteil des Systems. Hier ist die Grundidee:

  • Irgendwo haben Sie eine Registrierungstabelle eingerichtet. Wenn Sie Delphi XE verwenden, können Sie dies als TDictionary<string, TMyClassType> implementieren, wobei TMyClassType als class of TMyClass definiert ist. Das ist wichtig. Sie benötigen eine Zuordnung zwischen Klassennamen und Klassentypreferenzen.
  • Setzen Sie einen virtuellen Konstruktor auf TMyClass. Alles, was davon abstammt, wird diesen Konstruktor benutzen oder überschreiben, wenn das Fabrikmuster es erzeugt.
  • Wenn Sie eine neue abgeleitete Klasse erstellen, müssen Sie eine Methode aufrufen, die sich bei der Registrierungstabelle registriert. Dies sollte beim Programmstart geschehen, entweder in Initialisierung oder in einem Klassenkonstruktor.

Wenn Sie etwas aus einem Skript instanziieren müssen, tun Sie Folgendes:

%Vor%

Sie verwenden die Registrierungstabelle, um die Klassenreferenz vom Klassennamen abzurufen, und rufen den virtuellen Konstruktor für die Klassenreferenz auf, um den richtigen Objekttyp daraus zu ermitteln.

    
Mason Wheeler 28.09.2011 21:32
quelle
5

Ja, es ist technisch möglich, eine Instanz aus einer Klassenmethode zu erstellen, einfach den eigentlichen Konstruktor aufzurufen und dann die von ihm erzeugte Instanz zurückzugeben, zB:

%Vor%

In diesem Fall ist es besser, den Konstruktor direkt zu verwenden:

%Vor%     
Remy Lebeau 29.09.2011 00:51
quelle
1

Eine andere Möglichkeit ist die Verwendung von RTTI. Der folgende Code wird als normale Methode in meiner Klasse ausgeführt, um eine neue Instanz des Objekts mit einer Teilmenge von Elementen zu erhalten, da die Objekte (zusammen mit dem Listenobjekt selbst) wahrscheinlich aus untergeordneten Objekten bestehen und eine Instanz von Das Objekt, in dem die Methode definiert ist, ist nicht gut genug, da es vom gleichen Typ der Instanz sein muss.

d. h.

%Vor%

Die Implementierung von GetSubRange wäre etwas wie ...

%Vor%

Ich schätze für einige Dinge, dass es ein bisschen OTT sein kann, aber im obigen Design funktioniert es und ist eine andere Alternative, obwohl ich schätze, es ist keine Klassenmethode.

    
Steve Childs 31.01.2014 14:29
quelle
0

Sie sollten einen Konstruktor verwenden (eine spezielle "Art" der Klassenfunktion). TObject.NewInstance ist keine geeignete Option, es sei denn, Sie benötigen eine spezielle Speicherzuweisung.

Und in Bezug auf die Execute-Routine der Befehlsliste: Die betroffene Aktion hängt nun vom Typ des Objekts ab. Stellen Sie sich ein Dokument vor, das gleichzeitig öffnen, drucken, einfügen und speichern kann (keine seltsame Annahme), was in dieser Struktur schwer zu implementieren wäre. Ziehen Sie stattdessen in Betracht, Interfaces hinzuzufügen (IOpenDocument, IPasteFromClipboard, IPrintable, ISaveDocument), die in der Tat alle Aktionen einer Dokumenteninstanz sein könnten.

    
NGLN 28.09.2011 21:32
quelle