Hallo.
Vielen Dank für die Antwort. Ich habe wie gesagt in diesem Fall jetzt die Metaklassen-Variante vorgezogen, weil ich mir hierdurch viel Codezeilen an Clone()-Funktionen spare.
Ich habe bei der Implementierung selbst herausgefunden, wieso das virtual+override doch wichtig war. Ich hatte 4 Varianten durchprobiert, die sich kompilieren liesen und auf dem ersten Blick zu funktionieren schienen:
1. Kopie := TBasis(Original.NewInstance);
2. Kopie := TBasis(Original.ClassType.Create);
3. Kopie := TBasis(Original.ClassType).Create;
4. Kopie := TBasis(Original.ClassType).Create; // + TBasis.Create als virtual;
Die Instanz wurde bei allen vier Programmen korrekt initialisiert und erhielt einen eigenen Speicherabschnitt.
Aber: Felder, die im Konstruktor deklariert waren, waren bei Variante 1-3 leer! Deswegen war noch Variante 4 die korrekte Lösung.
Hier noch mein kompletter Probecode:
Delphi-Quellcode:
type
TBasisClass = class of TBasis;
TBasis = class(TObject)
F: String;
Test: string;
constructor Create; virtual;
end;
TAbleitung = class(TBasis)
constructor Create; override;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Original, Kopie: TBasis;
begin
Original := TAbleitung.Create;
Original.Test := 'A';
Kopie := TBasisClass(Original.ClassType).Create;
Kopie.Test := 'B';
showmessage('Feld Original: ' + Original.F); // "Ableitung"
showmessage('Feld Kopie: ' + Kopie.F); // "Ableitung" (nur bei virtual constructor)
end;
constructor TBasis.Create;
begin
inherited;
F := 'Basis';
end;
constructor TAbleitung.Create;
begin
inherited;
F := 'Ableitung';
end;
Jetzt weiß ich auch endlich, was virtual bedeutet: Die Adresse der Methode wird zur Laufzeit ermittelt und nicht zur Compilerzeit. Das ist ja bei mir notwendig, da ich eine Instanz eines unbekannten Derivats erzeugen will. Man lernt nie aus.
Gruß
blackdrake