Autor |
Beitrag |
Matclou
      
Beiträge: 24
|
Verfasst: Mi 10.08.11 14:20
Hallo,
ich habe eine Frage zum Finden von Instanzen!
Und zwar müsste es ja eigentlich eine Möglichkeit, alle Instanzen einer Klasse irgendwie aufzulisten. Funktioniert das auch mit FindComponent? Oder gibt es da noch andere Methoden, mit denen man auf bestehende Instanzen zugreifen kann?
Habe wohl eine etwas ältere Delphi-Version. Kann leider nicht genau sagen, welche es ist, weil ich sie gerade nicht vorliegen habe. Müsste aber, soweit ich mich erinnere 6 sein.
Vielen Dank im Voraus für die Hilfe!
Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 10.08.2011 um 16:59
Zuletzt bearbeitet von Matclou am So 14.08.11 14:26, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 10.08.11 17:03
Moin!
Matclou hat folgendes geschrieben : | Und zwar müsste es ja eigentlich eine Möglichkeit, alle Instanzen einer Klasse irgendwie aufzulisten. |
Nein, AFAIR gibt es in Delphi keine Möglichkeit eine Liste der instanziierten Klassen zu erhalten (das ist ja im Wesentlichen das, was auf dem Heap liegt). Einige separate Speichermanager (z.B. FastMM4) können nicht wieder freigegebene Instanzen beim Programmende auflisten, aber das war´s auch schon.
Fazit: Du musst dir beim Erzeugen von Instanzen diese merken und selbst wieder freigeben.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Für diesen Beitrag haben gedankt: Matclou
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: Mi 10.08.11 17:37
Ich hab's schon fast befürchtet^^ Habe allerdings eine Notlösung im Hinterkopf: Ich nehme als Oberklasse meiner Klasse einfach die Klasse tImage und lasse die Eigenschaft visible einfach auf Dakar stehen... Das müsste man dann ja auch als Komponente auflisten lassen können mit den entspr. Methoden.
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mi 10.08.11 18:27
Ich verstehe zwar nicht ganz was du vor hast (Dakar?) aber es hört sich so an, als wolltest du per FindComponent deine eigenen Objekte suchen.
Warum machst du nicht ein array mit deinen Instanzen?
Oder auch möglich, du machst dir eine Factory als Oberklasse, die dann dieses Array intern hält. Dann siehst du davon außen nix. Von außen hättest du dann sowas in der Art:
Delphi-Quelltext 1: 2:
| Fabrik.ErzeugeEinNeuesObjekt; Fabrik.AlleObjekteLöschen; |
Jetzt könnte man darin noch mehr verstecken, so dass man dann z.B. schnell ein bestimmtes Objekt suchen könnte. Oder alle Objekte um eins nach rechts rücken... Je nachdem was du vorhast.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: Matclou
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: Mi 10.08.11 19:59
Dakar klingt doch einfach klasse!  Nein, mein iPod hat eine sehr dämliche Autokorrektur, die mir gewissermaßen meine Mündigkeit abnimmt ein Wort richtig zu schreiben^^ Schon seltsam wie er von "false" auf "Dakar" kommt
Trotzdem hast du die Idee richtig verstanden. Was deinen Vorschlag angeht:
Auf die Idee bin ich irgendwie noch gar nicht gekommen^^^
Verstehe ich das richtig: Ich müsste also, wenn eine Instanz einer Klasse zur Laufzeit erstellt wird, gleichzeitig das Objekt quasi zur Sortierung in einem Array speichern?
Es müsste sich also um folgende Variable handeln:
Delphi-Quelltext 1:
| var ArrayMeineKlasse : array of tMeineKlasse |
Und gespeichert werden müsste das Objekt dann zu diesem Zeitpunkt:
Delphi-Quelltext 1: 2:
| NeueInstanz:=tMeineKlasse.create; array[0]:=NeueInstanz |
Ich bin etwas eingerostet, gab es zwischen ein- und zweidimensionalen Arrays irgendeinen Unterschied bei der Deklaration?
|
|
Lemmy
      
Beiträge: 792
Erhaltene Danke: 49
Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
|
Verfasst: Do 11.08.11 06:02
Guten Morgen,
für so was nimmt man im allgemeinen kein Array sondern eine TObjectList. Ist wesentlich einfacher zu handhaben.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var oList:TObjectLIst; ....
var oTest:TMeineKlasse; begin oTest:=TMeineKlasse.Create; oList.Add(oTEst); ... |
Vorteile gegenüber Array: Es sind bel. viele Elemente erlaubt und man muss sich nicht wie bei einem dynamischen Array um den Speicherplatz kümmern. Gibt man bei der Erzeugung der Liste noch den Parameter beim Create an, werden die Objekte in der liste auch automatisch freigegeben.
Grüße
Für diesen Beitrag haben gedankt: Matclou
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 11.08.11 08:48
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: Matclou
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: Fr 12.08.11 22:24
Lemmy hat folgendes geschrieben : | Guten Morgen,
für so was nimmt man im allgemeinen kein Array sondern eine TObjectList. Ist wesentlich einfacher zu handhaben.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var oList:TObjectLIst; ....
var oTest:TMeineKlasse; begin oTest:=TMeineKlasse.Create; oList.Add(oTEst); ... |
Vorteile gegenüber Array: Es sind bel. viele Elemente erlaubt und man muss sich nicht wie bei einem dynamischen Array um den Speicherplatz kümmern. Gibt man bei der Erzeugung der Liste noch den Parameter beim Create an, werden die Objekte in der liste auch automatisch freigegeben.
Grüße |
Okay, das klingt ja ganz gut! Wie viele Elemente sind denn bei arrays erlaubt?
Und: Kann man in der ObjectList auch einfache Integerzahlen einschreiben oder geht das nicht?
EDIT: Das letzte dürfte nicht gehen, ich kann es mir auf jeden Fall nur schwerlich vorstellen. Seit welcher Delphi-Version gibt es die tOBjectList denn eigentlich? Die Frage scheint mir auch noch wichtig zu sein
Vielen Dank im Voraus für die Hilfe!
|
|
Lemmy
      
Beiträge: 792
Erhaltene Danke: 49
Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
|
Verfasst: Fr 12.08.11 23:00
Matclou hat folgendes geschrieben : |
Okay, das klingt ja ganz gut! Wie viele Elemente sind denn bei arrays erlaubt?
|
ich arbeite schon lange nicht mehr mit Arrays, aber dynamische Arrays heißen eben so weil sie theoretisch bel. groß werden können - so groß wie dein Arbeitsspeicher ausreicht...
Matclou hat folgendes geschrieben : |
Und: Kann man in der ObjectList auch einfache Integerzahlen einschreiben oder geht das nicht? |
Nicht wirklich - deshalb heißt das ja auch TObjectList. Es gibt nen Trick, aber das würde ich nicht empfehlen, weil das dann Stellen sind an denen später Fehler auftreten oder die dann ausgebessert/geändert werden, wenn ein bestimmtes Verhalten geändert wird.
Typisches Beispiel aktuell: Jede Komponente der VCL hat ein Tag-Property. Das ist ein Integer. Nun ist es so, dass Zeiger ebenso im Grunde 32Bit Integer sind mit der Adresse auf die sie zeigen. Und so war es kein Problem einem Tag-Property einen Zeiger zuzuweisen.
Jetzt kommt der 64Bit Compiler - da geht das dann aber schief, weil der Integer 32Bit-breit bleibt, der Zeiger aber 64-Bit breit ist, was dann zu lustigen Auswirkungen und im besten Fall in einer klaren Fehlermeldung endet...
Matclou hat folgendes geschrieben : |
Seit welcher Delphi-Version gibt es die tOBjectList denn eigentlich? Die Frage scheint mir auch noch wichtig zu sein
|
In Delphi 5 ist sie auf jeden Fall dabei. Du musst die Unit contnrs einbinden. Und sollte es TObjectList nicht geben, dann kannst Du immer noch die TList nehmen, die sollte eigentlich auch schon bei Delphi 3 dabei sein...
Grüße
*Nachtrag
Wenn du unbedingt Texte oder Zahlen zu deinem Objekt speichern willst, dann kannst Du auch eine TStringList nehmen - in die kannst Du bel. Texte und auch Objekte an einer Position speichern. Allerdings weiß ich nicht auswendig, ob das in den älteren Delphi_Versionen schon geht...
Für diesen Beitrag haben gedankt: Matclou
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: So 14.08.11 13:19
Folgendes: Ich lasse Objekte vom Typ tKomponist aus der Objektliste olkomponisten in der ListBox lbkomponisten anzeigen. Das funktioniert einwandfrei. Wenn ich aber einen Komponisten löschen will, wird eine Fehlermeldung angezeigt: "Format '%p' ungültig oder nicht kompatibel mit Argument".
Es liegt offensichtlich an der Programmzeile "olkomponisten.delete(i)". Delete ist offiziell keine Methode von tobjectlist sondern eine von tlist vererbte. In der Delphi-Hilfe heißt es: "Mit Delete wird das Element an der bezeichneten Position aus der Liste gelöscht.".
Müsste doch eigentlich funktionieren, oder? Was mache ich falsch? Und: Wird mit Delete nur der Listeneintrag oder auch das Objekt gelöscht. Sonst wäre ja "hilfkomponist.destroy" unnötig.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TGUI.BtKomponistloeschenClick(Sender: TObject); var hilf: string; var hilfobjekt: tobject; var hilfkomponist: tkomponist; var i,j: integer; begin hilf:=Lbkomponisten.Items[Lbkomponisten.ItemIndex]; for i:=0 to anzahlkomponisten-1 do begin hilfobjekt:=OlKomponisten.Items[i]; hilfkomponist:=tkomponist(hilfobjekt); if hilfkomponist.getname = hilf then begin lbkomponisten.deleteselected; olkomponisten.delete(i); hilfkomponist.destroy; end; end; |
Nachtrag: Ohne das hilfskomponist.destroy und mit einem kleinem Zusatz funktioniert es jetzt  War nur ein "Variablenfehler", wenn ich das mal so nennen darf 
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 14.08.11 13:33
Erstens: Wenn du dem Konstruktor deiner Objektliste als Parameter True mitgibst, wird das Objekt beim Entfernen aus der Liste auch freigegeben.
Zweitens: Wie auch in der Delphi-Hilfe steht, sollte Destroy niemals direkt aufgerufen werden, sondern immer Free oder FreeAndNil.
Für diesen Beitrag haben gedankt: Matclou
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: So 14.08.11 13:55
Gut, danke für die beiden Hinweise
Ich bekomme nun übrigens beim Löschen regelmäßig den Hinweis der Listenindex überschreite das Maximum...
Der Listenindex kann sich ja im Prinzip nur auf die tobjectlist beziehen, oder? Eine Listbox hätte da doch andere Bezeichnungen, oder?
--- Moderiert von Narses: Beiträge zusammengefasst---
Hier nochmal alle relevanten Methoden und Delkarationen!
BtKomponistenClick -> Erstellt neues Objekt, aktualisiert die Liste
BtKomponistloeschenClick -> Löscht Objekt und seinen Namen aus der Liste
einfuegen -> fügt ein neues Objekt an der richtigen Stelle in die Objektlist ein, nimmt hierfür eine unsichtbare, sortierte Listbox zur Hilfe
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
| uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, mkomponist, Contnrs, ExtCtrls ;
type TGUI = class(TForm) BtWerk: TButton; BtKomponist: TButton; BtInterpret: TButton; BtCD: TButton; LabKomponistenname: TLabel; EdKomponistenname: TEdit; Lbkomponisten: TListBox; EdKomponistensortierung: TEdit; LabKomponistensortierung: TLabel; LbKomponistenSortieren: TListBox; BtKomponistInfobutton: TButton; LabKomponistenInfoName: TLabel; LabKomponistenInfoSortierung: TLabel; LabKomponistenInfoID: TLabel; LabKomponistenInfoNameBeschriftung: TLabel; LabKomponistenInfoSortierungBeschriftung: TLabel; LabKomponistenInfoIDBeschriftung: TLabel; BtKomponistloeschen: TButton; procedure BtKomponistClick(Sender: TObject); procedure BtAktualisierenLbKomponistenClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure BtKomponistInfobuttonClick(Sender: TObject); procedure BtKomponistloeschenClick(Sender: TObject); private procedure einfuegen(sortierung:string; komponist:tkomponist);
public OlKomponisten: tObjectList; idkomponistenfortlaufend:integer; end;
var GUI: TGUI;
implementation
{$R *.dfm}
procedure TGUI.BtKomponistClick(Sender: TObject); var NeuerKomponist,hilfskomponist: tKomponist; var hilf:integer; var hilfobjekt: tobject; begin NeuerKomponist:=tkomponist.create; Neuerkomponist.setname(Edkomponistenname.text); Neuerkomponist.setsortierung(Edkomponistensortierung.text); Neuerkomponist.setid(idkomponistenfortlaufend); einfuegen(neuerkomponist.getsortierung, neuerkomponist); idkomponistenfortlaufend:=idkomponistenfortlaufend+1; lbkomponisten.clear; for hilf:=0 to olkomponisten.count-1 do begin hilfobjekt:=OlKomponisten.items[hilf]; hilfskomponist:=tkomponist(hilfobjekt); LbKomponisten.Items.Add(hilfskomponist.getname); end; EdKomponistenname.text:=''; EdKomponistensortierung.text:=''; end;
procedure TGUI.FormActivate(Sender: TObject); begin OlKomponisten:=TObjectList.create(true); idkomponistenfortlaufend:=1; end;
procedure tgui.einfuegen(sortierung:string; komponist: tkomponist); var hilf: integer; var hilfstring: string; begin LbKomponistenSortieren.items.add(sortierung); for hilf:= 0 to lbkomponistensortieren.count-1 do begin hilfstring:=LbKomponistenSortieren.items[Hilf]; if hilfstring = sortierung then OlKomponisten.insert(hilf, komponist); end; end;
procedure TGUI.BtKomponistloeschenClick(Sender: TObject); var hilf: string; var hilfobjekt: tobject; var hilfkomponist: tkomponist; var i,j: integer; begin hilf:=Lbkomponisten.Items[Lbkomponisten.ItemIndex]; for i:=0 to olkomponisten.count-1 do begin hilfobjekt:=OlKomponisten.Items[i]; hilfkomponist:=tkomponist(hilfobjekt); if hilfkomponist.getname = hilf then begin lbkomponisten.deleteselected; olkomponisten.delete(i); end; end; end; end. |
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 14.08.11 14:30
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: Matclou
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 14.08.11 14:34
Mal so nebenbei:
Dein Quelltext sieht grauenhaft aus, keine Einrückungen...
Wenn du den besser formatieren würdest, würde man da auch schneller durchblicken...
|
|
Matclou 
      
Beiträge: 24
|
Verfasst: So 14.08.11 15:05
Hhm, ich glaube downto kennt meine Delphi-Version noch nicht
Aber danke schon mal für das FInden der Fehlerquelle, ich find da schon was 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 14.08.11 15:34
Moin!
Matclou hat folgendes geschrieben : | Hhm, ich glaube downto kennt meine Delphi-Version noch nicht  |
Das das Turbo-Pascal schon kannte, halte ich das für unwahrscheinlich.  Schau nochmal genau hin...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 14.08.11 16:10
Oder du sagst uns was für ein Fehler in welcher Zeile kommt. 
|
|
|