![]() |
Richtige Objekt-Kopie? Aber wie?
Ok ich habe mal was ganz feines, wozu ich nicht gerade die passende Lösung parrat habe...
Ich habe verschiedene voneinander abgeleitete Klassen:
Delphi-Quellcode:
Von diesen Klassen gibt es, wer hätte es gedacht, weitere Ableitungen und dies verschieden tief...
TParameterBase = Class
// ... TParameter = Class( TParameterBase ) // ... TParamererCollection = Class( TParameterBase ) // ... TParameterCollectionList = Class( TParameterBase ) Nun habe ich an einer Stelle ein Problem, dass ich eine Kopie eines Objekts benötige! Als vorbereitende Maßnahme hab ich natürlich die Basisklasse "TParameterBase" mit einer virtuellen Assign-Methode versehen, welche auch fein durch alle Klassen gepflegt wurde.. =] Problem ist aber, wie erzeuge ich ein Objekt einer Klasse, die ich im schlimmsten Fall nur über den "untersten" Vertreter "TParameterBase" kenne, um "Assign" aufzrufen? Das dümmste was mir ATM einfällt, wäre die Basisklasse mit einer virtuellen "GetCopie" Methode auszustatten und diese überall nachzupflegen... Nunja, ich halte diese Lösung aber für nicht so gut... ;) Eventuell hat ja jemand einen viel viel besseren Vorschlag... Bye Christian |
Re: Richtige Objekt-Kopie? Aber wie?
Ich habe das für meine Kurven-Hierarchie mit Basisklasse TKurve so gelöst:
Delphi-Quellcode:
type
TKurve = class(TPureInterfacedObject, IDrawable) private constructor CreateRaw; // nur fürs Klonen //... public //... function Clone: TKurve; procedure Assign(AKurve: TKurve); virtual; //... end;
Delphi-Quellcode:
Vielleicht nützt dir das was.
constructor TKurve.CreateRaw;
begin inherited Create; end; function TKurve.Clone: TKurve; type TKurvenClass = class of TKurve; begin // Da der Konstruktor über ClassType aufgerufen wird (und nicht direkt // TKurve.CreateRaw), wird eine Instanz des richtigen Typs erzeugt: Result := TKurvenClass(ClassType).CreateRaw; Result.Assign(Self); Assert(Result.ClassType = ClassType); end; Ciao, Uli. |
Re: Richtige Objekt-Kopie? Aber wie?
hmm ein ClassType.Create sollte doch allein schon ausreichen oder? Ich werd es mal testen. :cyclops:
Bye Christian |
Re: Richtige Objekt-Kopie? Aber wie?
Zitat:
|
Re: Richtige Objekt-Kopie? Aber wie?
Hmm die Klasse wird zwar erstellt, aber scheinbar ohne das der Constructor aufgerufen wird... :oops:
Was schlussendlich dazu führt, dass an ein paar Stellen baba passsiert... Bye Christian |
Re: Richtige Objekt-Kopie? Aber wie?
Bei nachfolgendem Testprojekt passiert bei mir kein Baba. (Wenn wir bei Baba an das Gleiche denken. :))
CloneAssignTest.dpr:
Delphi-Quellcode:
CloneAssign.pas:
program CloneAssignTest;
{$APPTYPE CONSOLE} uses SysUtils, CloneAssign in 'CloneAssign.pas'; var b1, b2: TBasis; begin b1 := TAbgeleitetS.Create('StringDing', 'Blah'); try b2 := b1.Clone; Writeln(b1.ToString); Writeln(b2.ToString); finally b1.Free; end; b1 := TAbgeleitetI.Create('IntDing', 4711); try b2 := b1.Clone; Writeln(b1.ToString); Writeln(b2.ToString); finally b1.Free; end; Readln; end.
Delphi-Quellcode:
Haut das bei dir auch hin?
unit CloneAssign;
interface type TBasis = class strict private FName: string; public constructor Create(const AName: string); function Clone: TBasis; procedure Assign(Source: TBasis); virtual; function ToString: string; virtual; end; TAbgeleitetS = class(TBasis) strict private FText: string; public constructor Create(const AName, AText: string); procedure Assign(Source: TBasis); override; function ToString: string; override; end; TAbgeleitetI = class(TBasis) strict private FCount: Integer; public constructor Create(const AName: string; ACount: Integer); procedure Assign(Source: TBasis); override; function ToString: string; override; end; implementation uses SysUtils; { TBasis } constructor TBasis.Create(const AName: string); begin inherited Create; FName := AName; end; function TBasis.Clone: TBasis; begin // Da der Konstruktor über ClassType aufgerufen wird (und nicht direkt // TBasis.CreateRaw), wird eine Instanz des richtigen Typs erzeugt: Result := TBasis(ClassType.Create); Assert(Result.ClassType = ClassType); Result.Assign(Self); end; procedure TBasis.Assign(Source: TBasis); begin FName := Source.FName; end; function TBasis.ToString: string; begin Result := FName + ': ' + ClassName; end; { TAbgeleitetS } constructor TAbgeleitetS.Create(const AName, AText: string); begin inherited Create(AName); FText := AText; end; procedure TAbgeleitetS.Assign(Source: TBasis); begin inherited Assign(Source); FText := TAbgeleitetS(Source).FText; end; function TAbgeleitetS.ToString: string; begin Result := inherited ToString + sLineBreak + ' Text = "' + FText + '"'; end; { TAbgeleitetI } constructor TAbgeleitetI.Create(const AName: string; ACount: Integer); begin inherited Create(AName); FCount := ACount; end; procedure TAbgeleitetI.Assign(Source: TBasis); begin inherited Assign(Source); FCount := TAbgeleitetI(Source).FCount; end; function TAbgeleitetI.ToString: string; begin Result := inherited ToString + sLineBreak + ' Count = ' + IntToStr(FCount); end; end. |
Re: Richtige Objekt-Kopie? Aber wie?
Hallo ihr beiden,
am Code von Uli sticht mir der statische Konstruktor ins Auge. Um auf TParameterBase aufbauende Klassen in einer Factory einsetzen zu können ist der virtuelle Konstruktor mit gleichbleibender Signatur gefragt. Hier nur grob skizziert - die Übertragung auf eine Methode statt einer stand-alone function dürfte nicht schwer fallen:
Delphi-Quellcode:
Dass der gewünschte Konstruktor bei Christians Versuch mit ClassType.Create nicht ausgeführt wird liegt daran, dass mit diesem Aufruf nur der statische Konstruktor von TObject errreicht wird. Das sollte im direkten Vergleich mit dem Code aus meiner Beispiel-Funktion klar werden.
type
TParameterBase = class public constructor Create; virtual; end; TParameter = class(TParameterBase) public constructor Create; override; end; TParameterBaseClass = class of TParameterBase; function Clone(p: TParameterBase): TParameterBase; begin Result := TParameterBaseClass(p.ClassType).Create; Result.Assign(p); end; Freundliche Grüße vom marabu |
Re: Richtige Objekt-Kopie? Aber wie?
Hallo, marabu!
Zitat:
Zitat:
Zugegebenermaßen kam mir mein Vorgehen am Anfang auch etwas wagemutig vor, aber es funktioniert seit einiger Zeit in einem realen Projekt. Uli. |
Re: Richtige Objekt-Kopie? Aber wie?
Guten Morgen,
Zitat:
Zitat:
Freundliche Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:26 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 by Thomas Breitkreuz