![]() |
Constructor from Instance
Guten Tag.
Weiß jemand wie man einen Constructor von einer Instanz aufruft? Zum verstehen eine Kleines Beispiel:
Code:
Die eigentliche Klasse ist von TPersistent abgeleitet und hat schon funktionstüchtig AssignTo mittels RTTI implementiert.
type
TAnimal = class public Name:String; end; TDog = class(TAnimal) public Hairs:Integer; end; TCat = class(Tanimal) public Color:Integer; end; var Animal1,Animal2:TAnimal; begin Animal1 := TDog.Create; //Some Code Animal2 := Animal1.Create; // << Das funktioniert nicht. Animal1 wird überschrieben. Animal2 := Animal1.Class.Create; // << Auch das funktioniert nicht. Wird dann ein TObject. Und gelegentlich muss ich von einer Instanz erstellen. Ich an folgendes gedacht:
Code:
Aber denke das geht vielleicht auch einfacher.
type
TAnimal = class public Name:String; procedure New:TAnimal; virtual; abstract; end; TDog = class(TAnimal) public Hairs:Integer; procedure New:TAnimal; override; end; TCat = class(Tanimal) public Color:Integer; procedure New:TAnimal; override; end; procedure TDogNew:TAnimal; begin Result := TDog.Create; end; var Animal1,Animal2:TAnimal; begin Animal1 := TDog.Create; //Some Code Animal2 := Animal1.New; Vielen Dank im vorraus. |
AW: Constructor from Instance
Als erstes würde ich TAnimal mal einen virtuellen Konstruktor verpassen.
Und die Variante mit
Delphi-Quellcode:
müsste prinzipiell funktionieren, wenn du etwas ergänzt:
Class
Delphi-Quellcode:
(freihändig hingetippt)
type
TAnimalCLass = class of TAnimal; // Stichwort "Class reference" oder "Metaklasse" Animal2 := TAnimalCLass(Animal1.Class).Create; |
AW: Constructor from Instance
Jetzt noch ClassType statt Class und dann geht's! :thumb:
Delphi-Quellcode:
type
TAnimal = class public Name: String; end; TDog = class(TAnimal) public Hairs: Integer; end; TCat = class(TAnimal) public Color: Integer; end; TAnimalClass = class of TAnimal; var Animal1, Animal2: TAnimal; begin try Animal1 := TDog.Create; Animal2 := TAnimalClass(Animal1.ClassType).Create; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: Constructor from Instance
Zitat:
Zitat:
|
AW: Constructor from Instance
Zitat:
Man benutzt zum Erstellen NIEMALS keine Variable, sondern immer den Typ. ALSO
Delphi-Quellcode:
denn sowas will und sollte man, nach Möglichkeit, nicht machen:
//Animal2 := Animal1.Create; {NEIN}
Animal2 := TAnimal.Create;
Delphi-Quellcode:
Animal2 := TAnimal(TAnimal.NewInstance);
Animal2.Create; Zitat:
Dass es dir das Objekt in Variable Animal1 überschrieben hat, ist korrekt. Mehr Spaß hättest du mit
Delphi-Quellcode:
, denn diese Variable war noch nicht initialisiert und es hätte hoffentlich eine schöne Exception gegeben. :angle2:
Animal2 := Animal2.Create;
Zitat:
Delphi-Quellcode:
Animal2 := TAnimal(Animal1.NewInstance);
Animal2.Create; |
AW: Constructor from Instance
Delphi-Quellcode:
Das funktioniert einwandfrei. Vielen Dank
Animal2 := TAnimalClass(Animal1.ClassType).Create;
|
AW: Constructor from Instance
Zitat:
|
AW: Constructor from Instance
Ja, das ist richtig.
uligerhardt hatte zwar geschrieben dass es auch ohne geht. Das Allerdings nur bedingt und damit nicht richtig. Man kann alle Felder benutzen aber der abgeleitete Constructor wird nicht aufgerufen. Im Beispiel gab es keinen. Deswegen ist es nicht aufgefallen. Virtueller und in abgeleiteter Klasse überschriebener Constructor und es funktionier einwandfrei. Wenn man solche speziellen Sachen macht muss man natürlich noch mehr darauf achten, dass nachher alles wieder freigegeben wird. Das war bei mir aber gegeben durch:
Delphi-Quellcode:
type
TAnimalList = class(TObjectList<TAnimal>) public constructor Create; reintroduce; end; constructor TAnimalList.Create; begin inherited Create(true); //AOwnsObjects end; |
AW: Constructor from Instance
Bei der Liste muß es nicht sein,
aber wenn TDog und TCat einen eigenen Constructor haben sollen. Wie bei den TComponent-Nachfahren, welche man auf die Form pappen kann und wo der DFM-Loader natürlich nur TComponent kennt. |
AW: Constructor from Instance
Zitat:
Bestenfalls wäre ein duplizieren einer Instanz, wozu ich dann immer eine explizite Methode ".Clone" dafür anlegen würde, die auch was entsprechend vorbereiten kann. Der einzige, mögliche Grund, der mit einfällt, könnte sein, wenn man von einer geschlossenen 3rd-Party Library nur eine Instanz bekommt, aber keinen Zugriff auf die Klassendefinition oder SourceCodes hat. Dann würde ich aber versuchen diese 3rd-Party Komponente so schnell wie möglich rauszuwerfen. Bitte klärt mich auf, wenn dafür doch wichtige Anwendungen gibt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz