Autor Beitrag
Matclou
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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 user profile iconNarses: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 10.08.11 17:03 
Moin!

user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:
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. :nixweiss:

Fazit: Du musst dir beim Erzeugen von Instanzen diese merken und selbst wieder freigeben. :idea:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: 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:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mi 10.08.11 19:59 
Dakar klingt doch einfach klasse! :D 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:

ausblenden Delphi-Quelltext
1:
var ArrayMeineKlasse : array of tMeineKlasse					


Und gespeichert werden müsste das Objekt dann zu diesem Zeitpunkt:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Do 11.08.11 08:48 
user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
var ArrayMeineKlasse : array of tMeineKlasse					


Und gespeichert werden müsste das Objekt dann zu diesem Zeitpunkt:

ausblenden Delphi-Quelltext
1:
2:
NeueInstanz:=tMeineKlasse.create;
array[0]:=NeueInstanz


Das reicht schon:
ausblenden Delphi-Quelltext
1:
ArrayMeineKlasse[0] := TMeineKlasse.Create;					



user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:
Ich bin etwas eingerostet, gab es zwischen ein- und zweidimensionalen Arrays irgendeinen Unterschied bei der Deklaration?


Zweidimensional wäre:
ausblenden Delphi-Quelltext
1:
var ArrayMeineKlasse: array of array of TMeineKlasse;					

_________________
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Fr 12.08.11 22:24 
user profile iconLemmy hat folgendes geschrieben Zum zitierten Posting springen:
Guten Morgen,

für so was nimmt man im allgemeinen kein Array sondern eine TObjectList. Ist wesentlich einfacher zu handhaben.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Fr 12.08.11 23:00 
user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:

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...


user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:

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...


user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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 user profile iconNarses: 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
ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    procedure einfuegen(sortierung:string; komponist:tkomponist);

  public
    { Public-Deklarationen }
    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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: So 14.08.11 14:30 
user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
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;

So kann das natürlich nicht gehen. Du gehst die Einträge durch, und zwar von vorne nach hinten, und löschst dabei aus der Liste raus. Am Ende willst du auf Count-1 zugreifen, es ist aber ein Eintrag weniger da. Fällt dir was auf? ;)

Probiers mal mit
for i:=olkomponisten.count-1 downto 0 do
Dann wird zwar der eine Eintrag nach dem Löschen zweimal geprüft, aber ich denke das machts nicht aus.

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.08.11 14:34 
Mal so nebenbei:
Dein Quelltext sieht grauenhaft aus, keine Einrückungen... :shock:
Wenn du den besser formatieren würdest, würde man da auch schneller durchblicken...
Matclou Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 14.08.11 15:34 
Moin!

user profile iconMatclou hat folgendes geschrieben Zum zitierten Posting springen:
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... :suspect: :les: :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.08.11 16:10 
Oder du sagst uns was für ein Fehler in welcher Zeile kommt. ;-)