![]() |
Ein Objekt zu Laufzeit die Klasse zuweisen
Ich hab ein etwas sonderbares Problem, bin mir aber sicher, dass es irgendwie zu realisieren geht. Nur fehlt mir hier etwas Wissen.
Ich beschreibe das Problem etwas vereinfacht: ich erstelle ein Objekt in einer Prozedur und gebe das Objekt in einer zweiten Prozedur frei. Soweit nichts besonderes, das Problem liegt aber im Detail. Ich beschreibe das Problem etwas genauer: ich erstelle in einer Prozedur ein beliebiges Objekt und übergebe es an ein TStrings Item. Beim löschen des Items in der zweiten Prozedur gebe ich zuerst das Objekt frei und lösche dann erst das Item. Das ist die normale Vorgehensweise, also immer noch nichts besonderes. Das Problem ist aber, dass das Objekt in der ersten Prozedur mal dieses, mal jenes sein kann. Ich muß also in der zweiten Prozedur den Typ immer anpassen. Das möchte ich mir sparen. Ich würde das gerne automatisieren wenn es geht. Nur bisherige Versuche schlugen fehl. Ich kann doch den Objekttyp aus dem Item auslesen. Wie kann ich also zu Laufzeit den Objekttyp einer Variable ändern? Letztendlich geht es um sowas in der Art:
Delphi-Quellcode:
Kann ich Tmp als Objekttyp zu Laufzeit anpassen?
procedure TForm1.FormDestroy(Sender: TObject);
var i: Integer; Tmp: TMyObj; begin with ListBox1 do for i := 0 to Items.Count - 1 do begin Tmp:= TMyObj(Items.Objects[i]); Tmp.Free; end; end; |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Delphi-Quellcode:
Das sollte doch vollkommen ausreichen, das Objekt dürfte ja seinen eigenen Destruktor kennen.
for i := 0 to ListBox1.Items.Count - 1 do
ListBox1.Items.Objects[i].Free; |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Was hält dich davon ab, das hier zu tun?
Delphi-Quellcode:
Manchmal sind die Dinge einfacher als gedacht :wink:
procedure TForm1.FormDestroy(Sender: TObject);
var i: Integer; begin with ListBox1 do for i := 0 to Items.Count - 1 do Items.Objects[i].Free; end; |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Oder einfach
![]() |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Das gibt es IIRC aber erst seit Delphi XE.
|
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Über Generics könnte man das im schlimmsten Fall auch noch lösen. :mrgreen:
|
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Aber wozu sollten einem die Generics helfen? Beim Freigen einer beliebigen Instanz?
Einfach freigen und gut, egal was das für eine Instanz ist (wenn es eine Instanz ist) |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Ok, in dem einem speziellem Fall scheint es wirklich einfacher zu sein als gedacht. Da habe ich anscheinend beim überlegen paar Ebenen übersprungen und erst an einem Punkt in der Mitte angefangen. Das ist um so erstaunlicher, da ich beim testen eigentlich auch schon soweit war, nur dem Ganzen nicht getraut habe, weil es für mich zu einfach war. Ich dachte es funktioniert nur zufällig. Bisher auf jeden Fall danke.
Trotzdem interessiert mich das Prinzip im allgemeinem. Jetzt weniger um ein Problem zu lösen als um die Machbarkeit festzustellen. |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Es ist auf jeden Fall nicht möglich eine Instanz auf eine andere Klasse umzustellen.
z.B. eine TStringList auf ein TButton |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Erstell dir eine Basisklasse und deklariere den constructor und destructor als virtual. Wenn du dann bei den konkreten Objekten die Methoden überschreibst, wird automatisch die richtige Funktion ausgeführt. Sind die Methoden nicht virtual, dann wird bei diesem Beispiel nur die Funktion der Basisklasse in Betracht gezogen.
|
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Zitat:
...:cat:... |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Zitat:
@Zacherl Wäre evtl. möglich, aber dann fängt es an wieder komplex zu werden. |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Dann hast du - entschuldige bitte - aber die Frage völlig falsch gestellt.
Denn du willst einer Objektvariablen zur Laufzeit eine andere Instanzreferenz zuweisen und nicht einem Objekt eine Klasse ;) Und wo ist das Problem? Um ganz sicher zu gehen, dass es funktioniert, definiere die Variable als TObject, dann kann dort jede Instanz-Referenz abgelegt werden, die von TObject abgeleitet wurde (also jede) Ok, per hartem Cast kann man auch alles machen, ist aber nicht ratsam. Wo ist denn das eigentliche Problem? Zeig doch mal ein wenig Code, wo du da ein Problem siehst. EDIT hmmm, suchst du so etwas wie das Visitor Pattern? Schau mal beim Uwe Raabe auf der Blogseite rein, der hat da in 4 Teilen etwas sehr kreatives abgeliefert |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Das eigentlich Problem ist, dass nichts bisher funktionierte was ich getestet habe. Vielleicht liegt das Problem im Detail. Ich mache noch paar Versuche.
//Edit: Nein, es funktioniert doch nicht. Wie gesagt, anscheinend habe ich beim ersten Mal das Problem richtig beschrieben, beim zweiten Mal zu Missverständnissen geführt. Aber letztendlich ist es egal, es war eher nur eine Idee und eine Frage der Machbarkeit. Kein eigentliches Problem, mehr Interesse. Aber wenn ich gerade so überlege, dann kann das nicht klappen. Selbst wenn es klappen würde, wahrscheinlich würde der Compiler es nicht mitmachen. Wenn ich z.B. Tmp.Canvas im Code eingebe, dann macht er das beim falschen Objekt sowieso nicht mit. |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Zitat:
Möchtest du evtl. in dieser Richtung?
Delphi-Quellcode:
Übergibst du eine TButton Instanz, soll die Caption geändert werden, übergibst du eine Instanz von TStringList, dann soll der Inhalt gelöscht werden.
procedure DoSomething( AInstance : TObject );
begin ... end; Suchst du sowas in der Art? |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Wie gesagt, inzwischen gehe ich davon aus, dass es nicht klappen kann. Aber ich beschreibe man meine Überlegungen noch mal mit meinen Beispiel aus dem ersten Beitrag (nur der Vollständigkeitshalber).
Delphi-Quellcode:
Wie gesagt, mich interessierte es nur ob das geht.
procedure TForm1.FormDestroy(Sender: TObject);
var i: Integer; Tmp: T???; begin with ListBox1 do for i := 0 to Items.Count - 1 do begin //An jedem Item hängt ein Objekt, nehmen wir an es ist ein TBitmap, aber ich weiß es nicht //Nun stellt sich die Frage ob ich Tmp im Betrieb zu dem Objekttyp machen kann der //am Item hängt. Also ermitteln, dass es TBitmap ist und Tmp zu TBitmap machen Tmp:= T???(Items.Objects[i]); //Das Free ist hier Sekundär und nur ein Beispiel. Das wird auch so klappen, da es jedes Objekt besitzt //Aber um das geht es weniger, sondern kann ich Tmp zuerst zu TBitmap machen und //es erst dann freigebe Tmp.Free; end; end; //Edit: Oder anders ausgedrückt
Delphi-Quellcode:
nur das ich die Info TBitmap aus dem Objekt an dem Item erfahre.
(Tmp as TBitmap)
.. |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Da es nur Sinn macht den Typen zu erfahren, wenn mit diesem Objekt etwas klassenspezifisches machen möchte (also z.B. der TBitmap-Instanz ein Bild zuweisen), denn ansonsten wäre der Typ egal, bzw. man muss nicht immer den ganz konkreten Typen wissen, wenn die geplante Aktion auch schon ein paar Klassen vorher implementiert ist/ansprechbar ist (z.B. die Eigenschaft Tag wird von TComponent eingeführt, darum müsste ich nicht auf TButton prüfen um das Tag zu setzen)
Also ist meine Vermutung schon richtig gewesen, dass du einen Visitor haben möchtest ;) Hier der Link zum Blog von Uwe ![]() |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Nur um sicher zu gehen, dass das Objekt weiß was es ist weißt Du?
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
begin Listbox1.Items.AddObject('',TButton.Create(self)); Listbox1.Items.AddObject('',TListbox.Create(self)); Listbox1.Items.AddObject('',TBitmap.Create); end; procedure TForm3.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); begin ListBox1.Canvas.FillRect(rect); ListBox1.Canvas.TextOut(rect.Left,rect.Top,ListBox1.Items.Objects[index].ClassName); end; |
AW: Ein Objekt zu Laufzeit die Klasse zuweisen
Zitat:
Delphi-Quellcode:
type
PClass = ^TClass; begin if MyObject is TBaseObject then PClass(MyObject)^ := TDerivedObject; ... end |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:52 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