Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Object dynamisch in einem Array erzeufen (https://www.delphipraxis.net/155162-object-dynamisch-einem-array-erzeufen.html)

gangs-taas 11. Okt 2010 19:48

Object dynamisch in einem Array erzeufen
 
Hey,
ich möchte gerne Shapes dynamisch erzeugen.
Dafür habe ich mir gedacht ich mach das in einem Array.
Ich mach das aber in einer zweiten Unit (um das schön objectorientiert zu machen ..).
Ich hab das wie folgt umgesetzt ABER trotzdem haben nach dem erzeugen alle Einträge in meinem Array den wert "Nil" und wenn ich damit weiter arbeiten möchte bekomme ich fehlermeldungne (weil ja nichts da ist zum drauf zugreifen .. )
könnt ihr mir sagen woran es liegt ?

Delphi-Quellcode:
procedure TVerw.Add_Ufo(Starty,StartX,Geschwin : integer;
                        Sender :TComponent; Unterlage : TWinControl);
begin
  SetLength(Ufo_Arr,Length(Ufo_Arr) + 1 );
  Ufo_Arr[Length(Ufo_Arr)] := TUfo.Create(StartX,StartY,Geschwin,Sender);
  Ufo_Arr[Length(Ufo_Arr)].Parent := Unterlage; // => das Form auf dem es Dargestellt werden soll
  Ufo_Arr[Length(Ufo_Arr)].Name := 'Ufo' + IntToStr(Length(Ufo_Arr)) ;
  Ufo_Arr[Length(Ufo_Arr)].Shape :=stCircle;
  Ufo_Arr[Length(Ufo_Arr)].Brush.Color := ClBlue ;
  Ufo_Arr[Length(Ufo_Arr)].Width := Ufo_Breite ;
  Ufo_Arr[Length(Ufo_Arr)].Height := Ufo_hoehe ;
  Ufo_Arr[Length(Ufo_Arr)].Show;

end;
außerdem habe ich die Create Routine ein wenig verändert, aber ich denke nicht, dass es daran liegt ..
nur zur sicherheit hier die veränderte Create Routine :
Delphi-Quellcode:
 
// Tufo ist vom Type TShape

 constructor TUfo.Create(StartKoX, StartKoY, Geschwindigkeit: integer; Owner : TComponent );
  begin
  inherited Create(Owner) ;
    Left := StartKoX ;
    Top := StartKoY ;
    Rich_Arr[1] := Geschwindigkeit ;
    Rich_Arr[2] := 0 ;
    Muenze := false ;
  end;

nachti1505 11. Okt 2010 20:04

AW: Object dynamisch in einem Array erzeufen
 
Dynamische Arrays sind imho Nullbasiert -->

Delphi-Quellcode:
Ufo_Arr[Length(Ufo_Arr)-1] := TUfo.Create(StartX,StartY,Geschwin,Sender);

gangs-taas 11. Okt 2010 20:08

AW: Object dynamisch in einem Array erzeufen
 
stimmt natürlich
immer mach ich die gleichen blöden fehlöer :/

Sir Rufo 11. Okt 2010 21:03

AW: Object dynamisch in einem Array erzeufen
 
Wenn du OOP machen möchtest dann nimm dafür die richtige Klasse TObjectList

David Martens 13. Okt 2010 01:02

AW: Object dynamisch in einem Array erzeufen
 
Hast du schon mal über "Templates" nachgedacht:

Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Unit : t_TypedObjectList                                                 //
// Quelle: www.dummzeuch.de/delphi/object_pascal_templates/deutsch.html      //
////////////////////////////////////////////////////////////////////////////////
// Erstellt von: David Martens                                               //
// Erstellt am : 10.11.2008                                                   //
// Beschreibung: Delphi-"Template" zur Erstellung typisierter Listen         //
////////////////////////////////////////////////////////////////////////////////
// Geändert von:                                                             //
// Geändert am :                                                             //
////////////////////////////////////////////////////////////////////////////////

{$IFNDEF LIST_TEMPLATE_}
unit t_TypedObjectList;

interface

{: These units must be added to the uses clause of any class built on this template }
uses
  Classes;

{: These types must be declared for each class built on this template }
type
  {: the ancestor class for the template, can be TObject or TInterfacedObject
     or anything else you like}
  _LIST_ANCESTOR_ = TObject;
  {: Container type used to actually store the items: TList or TInterfacelist }
  _LIST_CONTAINER_ = TList;
  {: The native item type of the list container (Pointer for TList, IInterface for TInterfaceList}
  _LIST_CONTAINER_ITEM_TYPE_ = pointer;
  {: The item type to be stored in the list }
  _ITEM_TYPE_ = TObject;

{$ENDIF LIST_TEMPLATE_}

{$IFNDEF LIST_TEMPLATE_SECOND_PASS_}

type
  _LIST_TEMPLATE_ = class(_LIST_ANCESTOR_)
  private
    {: This actually stores the items }
    FItems: _LIST_CONTAINER_;
    {: Getter function for Items property }
    function _GetItems(_Idx: integer): _ITEM_TYPE_;
  protected
    {: Frees an item (does nothing here, must be overwritten }
    procedure FreeItem(_Item: _ITEM_TYPE_); virtual;
  public
    {: Creates a list for storing items }
    constructor Create;
    {: Calls FreeItem for alle items and frees the list }
    destructor Destroy; override;
    {: Returns the number of items stored in the list }
    function Count: integer;
    {: Deletes all items from the list without calling FreeItem }
    procedure DeleteAll;
    {: Exchanges the two items at index Idx1 and Idx2 }
    procedure Exchange(_Idx1, _Idx2: integer);
    {: removes the item with index Idx from the list and returns it }
    function Extract(_Idx: integer): _ITEM_TYPE_;
    {: Calls FreeItem for all items and removes them from the list }
    procedure FreeAll;
    {: inserts an item into the list and returns its index }
    procedure Insert(_Idx: integer; _Item: _ITEM_TYPE_); virtual;

    function Add(_Item: Pointer): integer;
    {: allows accessing the items in the list by index }
    property Items[_Idx: integer]: _ITEM_TYPE_ read _GetItems; default;
  end;

{$ENDIF LIST_TEMPLATE_SECOND_PASS_}

{$IFNDEF LIST_TEMPLATE_}
{$DEFINE LIST_TEMPLATE_SECOND_PASS_}
implementation
{$ENDIF LIST_TEMPLATE_}

{$IFDEF LIST_TEMPLATE_SECOND_PASS_}

{ _LIST_TEMPLATE_ }

function _LIST_TEMPLATE_.Add(_Item: Pointer): integer;
begin
  Result := FItems.Add(_LIST_CONTAINER_ITEM_TYPE_(_Item));
end;

function _LIST_TEMPLATE_.Count: integer;
begin
  Result := FItems.Count;
end;

constructor _LIST_TEMPLATE_.Create;
begin
  inherited Create;
  FItems := _LIST_CONTAINER_.Create;
end;

procedure _LIST_TEMPLATE_.DeleteAll;
begin
  FItems.Clear;
end;

destructor _LIST_TEMPLATE_.Destroy;
var
  i: integer;
  Item: _ITEM_TYPE_;
begin
  if Assigned(FItems)
  then
  begin
    for i := 0 to FItems.Count - 1
    do
    begin
      Item := _ITEM_TYPE_(FItems[i]);
      FreeItem(Item);
    end;
  end;
  FItems.Free;
  inherited;
end;

procedure _LIST_TEMPLATE_.Exchange(_Idx1, _Idx2: integer);
begin
  FItems.Exchange(_Idx1, _Idx2);
end;

function _LIST_TEMPLATE_.Extract(_Idx: integer): _ITEM_TYPE_;
begin
  Result := _ITEM_TYPE_(FItems[_Idx]);
  Fitems.Delete(_Idx);
end;

procedure _LIST_TEMPLATE_.FreeAll;
var
  i: integer;
begin
  for i := 0 to FItems.Count - 1
  do
  begin
    FreeItem(_ITEM_TYPE_(FItems[i]));
  end;
  FItems.Clear;
end;

procedure _LIST_TEMPLATE_.FreeItem(_Item: _ITEM_TYPE_);
begin
  // do nothing, override if the items must be freed
end;

function _LIST_TEMPLATE_._GetItems(_Idx: integer): _ITEM_TYPE_;
begin
  Result := _ITEM_TYPE_(FItems[_Idx]);
end;

procedure _LIST_TEMPLATE_.Insert(_Idx: integer; _Item: _ITEM_TYPE_);
begin
  FItems.Insert(_Idx, _LIST_CONTAINER_ITEM_TYPE_(_Item));
end;

{$ENDIF LIST_TEMPLATE_SECOND_PASS_}

{$DEFINE LIST_TEMPLATE_SECOND_PASS_}

{$IFNDEF LIST_TEMPLATE_}
{$WARNINGS OFF}
end.
{$ENDIF LIST_TEMPLATE_}
Und hier ist ein kleines Beispiel um die Anwendung zu demonstrieren:

Das Objekt was in der Liste gespeichert werden soll:
Delphi-Quellcode:
unit u_FilterItem;

interface

type
  TFilterItem = class
  strict private
    FHeight : integer;
    FTop : integer;

    FControl : TControl;
    ...
  public
    constructor Create(aParent : TWinControl;
                       iName : integer;
                       Top : integer;
                       OnClick : TNotifyEvent;
                       OnChangeEvent : TNotifyEvent);

    destructor Destroy; override;

    ...

    property Height : integer read FHeight write SetHeight;
    property Top : integer read FTop write SetTop;
    ...
  end;

implementation

und er ganze Rest.......
also ein ganz normales Objekt.
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Erstellt von: David Martens                                               //
// Erstellt am: 10.11.2008                                                   //
// Beschreibung: typisierte Listklasse unter Verwendung eines                //
//               Delphi-"Templates"                                          //
//                                                                            //
//               In der "Listklasse" ist eine "Kontainerklasse" enthalten,   //
//               die die eigentliche Liste enthält.                          //
//                                                                            //
//               weitere Beschreibung in der Implementierung                 //
////////////////////////////////////////////////////////////////////////////////
unit u_FilterItemList;

interface

uses
  Classes,
  // Unit mit Klasse für _ITEM_TYPE_ (eine ganz normale Klasse)
  u_FilterItem;

// Kompilerdirektive für das Template
{$DEFINE LIST_TEMPLATE_}

type
  // Vorfahr der "Listklasse"
  _LIST_ANCESTOR_ = TObject;
  // Vorfahr der "Kontainerklasse", sollte ein Nachfahr von TList sein
  _LIST_CONTAINER_ = TList;
  // Typ des Items in der "Kontainerklasse" (z.B.: Pointer für TList, IInterface für TInterfaceList}
  _LIST_CONTAINER_ITEM_TYPE_ = pointer;
  // Item der typisierten Klasse, dieser Typ wird von der Klasse ausgegeben
  _ITEM_TYPE_ = TFilterItem;

// Verzeichnis: \Delphi\Komponenten\Templates nicht in Umgebungsvariablen vorhanden daher so:

// 1. Template-aufruf: erstellt den Kopf der _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}

type
  // "Umbenennung" von _LIST_TEMPLATE_ und weitere spezielle Eigenschaften für die Klasse
  TFilterItemList = class(_LIST_TEMPLATE_)
  protected
    // muss implementiert werden, falls die Items freigegeben werden müssen (destructor Aufruf)
    procedure FreeItem(_Item: _ITEM_TYPE_); override;
  end;

implementation

// 2. Template-aufruf: implementiert die _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}


// Implementierung der speziellen Eigenschaften der Klasse

{ TFilterItemList }

procedure TFilterItemList.FreeItem(_Item: _ITEM_TYPE_);
begin
  _Item.Free;

  inherited;
end;

end.
Zum Schluß, wie es angewendet wird:
Delphi-Quellcode:
    FFilterListe : TFilterItemList;

...

  if FFilterListe.Count > 0 then
  begin
    NewTop := FFilterListe.Items[FFilterListe.Count - 1].Top +
              FFilterListe.Items[FFilterListe.Count - 1].Height;
  end;
Kein typecating mehr :-D

gangs-taas 13. Okt 2010 12:18

AW: Object dynamisch in einem Array erzeufen
 
Hey,
viele Dank, für die sehr ausführlichen antworten .

zu TObjectList :
Ich sehe dort ehrlich gesagt nicht unbedigt sooo den vorteil im gegensatz zu einem Array ..
ist vllt einfacher elemente zu löschen o.ä. aber ansonsten seh ich keinen vorteil

zu Templates

ich denke, das ist kompizierte, als es sein muss,
vorallem, weil ich kein hochausgeklügeltes prgramm schreib, sondern äh.. ich einfach froh bin, wenn es hinterher das macht, was ich will
ich muss nicht alle lücken abdecken ..

trotzdem vielen dank

DeddyH 13. Okt 2010 12:24

AW: Object dynamisch in einem Array erzeufen
 
Noch ein Tipp zu Arrays: wann immer möglich solltest Du Low() und High() verwenden, damit bleibst Du garantiert innerhalb der Array-Grenzen.

Sir Rufo 13. Okt 2010 12:41

AW: Object dynamisch in einem Array erzeufen
 
Ich dachte du wolltest das "schön objektorientiert" machen.

Ein Array ist aber imho nicht oop

shmia 13. Okt 2010 14:53

AW: Object dynamisch in einem Array erzeufen
 
Diese Arrays für Komponenten oder Controls sind doch Käse!
Sorry, aber ich muss immer wieder feststellen, dass viele die Kurve zu OOP nicht kriegen.

Dabei gibt es neben TObjectList auch die Klasse TComponent.
Damit kann man die Objekte sehr elegant und mit geringstem Aufwand verwalten.

Hier ein Beispiel wie man TComponent als Ersatz für das Array benützt:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ButtonControlsErzeugen: TButton;
    ButtonControlsLoeschen: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ButtonControlsErzeugenClick(Sender: TObject);
    procedure ButtonControlsLoeschenClick(Sender: TObject);
  private
    { Private-Deklarationen }
    FMyList : TComponent;  // Ersatz für Array
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
   FMyList := TComponent.Create(Self);
   // Besitzer ist das Formular; FMyList braucht also nicht freigegeben werden
end;

procedure TForm1.ButtonControlsErzeugenClick(Sender: TObject);
var
   i : Integer;
   lbl : TLabel;
   edt : TEdit;
begin
   // dynamisch Komponenten erzeugen und in die Liste packen
   for i := 0 to 10 do
   begin
      lbl := TLabel.Create(FMyList {<==});
      lbl.Caption := Format('Label %d',[i]);
      lbl.Top := i * 15;
      lbl.Left := i * 9;
      lbl.Parent := Self;
   end;

   for i := 0 to 10 do
   begin
      edt := TEdit.Create(FMyList);
      edt.Text := Format('Edit %d',[i]);
      edt.Top := i * 15;
      edt.Left := 300 - i * 20;
      edt.Parent := Self;
   end;

end;

procedure TForm1.ButtonControlsLoeschenClick(Sender: TObject);
begin
   // alle Komponenten in der Liste zerstören
   FMyList.DestroyComponents;
end;
Auch die Typsicherheit lässt sich ganz einfach durch Ableiten von TComponent herstellen.
Bei Interesse kann ich das zeigen.

DeddyH 13. Okt 2010 15:26

AW: Object dynamisch in einem Array erzeufen
 
Es gibt btw. auch noch TComponentList.

gangs-taas 13. Okt 2010 17:00

AW: Object dynamisch in einem Array erzeufen
 
soo ich hab dann jetzt noch einmal ein paar frage :

1) OOP beduetet doch, dass ich die einzellnen Procedures und Properties "fest in ein objekt binde, so dass sie nach außen gekapselt erscheinen und nicht manipuliert werden können" (sinngemäß nach wikipedia)
ich versteh nicht warum ihr meint, dass die Array nicht OOP seien. Schließlich verwaltet das Array doch nur OBJEKTE (=> es gibt objekte => oop)
Was ist daran jetzt so falsch ? oder was hab ich noch nicht verstanden ?

2) zu dem code von shmia :
du schreibst, du würdest die Komponenten erzeugen und in die Liste packen
aber ich sehe einfach nicht, warum deine mehtode jetzt unbedigt so viel einfacher oder so wäre ...


lg

Sir Rufo 13. Okt 2010 17:37

AW: Object dynamisch in einem Array erzeufen
 
OOP fängt bei Delphi mit TObject an und baut sich darauf auf
Keine Arrays (das war damals) sondern TList (kommt von TObject) oder von TList abgeleitet.

Ein Großer Vorteil von OOP ist die Vererbung und das geht bei Array nicht

David Martens 13. Okt 2010 17:42

AW: Object dynamisch in einem Array erzeufen
 
Also ich finde Templates nicht schwierig.

Im Bezug auf mein voriges Posting:

- das erste Listing 1 zu 1 übernehmen
- der zweite Listing ist das Objekt das in der Liste gespeichert werden, ein ganz normales Objekt. Das hat nichts mit dem Template zu tun.
- das dritte Listing macht jetzt den Trick, dazu kann man einfach mein Listing nehmen und an den entscheidenden Stellen ändern. (Bei uses die Unit angeben und beim 1. type die Klasse angeben, ab dem 2. type KANN der Name der Liste geändert werden.)

Benutzung wie normales TList mit Typisierung.

Delphi-Quellcode:
  ObjectX := TObjectX.Create(...);
  ObjectXList := TObjectXList.Create(...);

  ObjectX.blabla := ....
  ...

  ObjectXList.Add(Object);

  ...
  ...

  ObjectXList.Items[i].blaba.....  (und nicht TObjectX(ObjectXList.Items[i]).blaba) oder
  ObjectXList[i].blaba.....        (und nicht TObjectX(ObjectXList[i]).blaba)
Hat den entscheidenden Vorteil, daß in der Liste immer Objekte vom gewünschten Typ sind und keine Fehler produziert wenn ein falsches typecasting (weil nicht nötig :-D) gemacht wird.

shmia 13. Okt 2010 17:45

AW: Object dynamisch in einem Array erzeufen
 
zu 1.)
Arrays sind relativ primitive Datentypen.
Das heisst jetzt nicht das an Arrays irgendetwas schlecht wäre;
es ist nur so, dass es Bausteine (Klassen und Objekte) auf höherer (Abstraktions-)Ebene gibt,
mit denen man bestimmte Dinge einfacher, besser und verständlicher lösen kann.

Man könnte eine Rangfolge (von primitiv bis abstrakt) der Datentypen aufstellen
1) char, integer, double, cardinal,...
2) array mit festen Grenzen, Aufzählungstypen
3) dynamische Arrays, Strings, Mengen
4) Records, Listen
5) Klassen
6) Templates
7) Zusammenarbeit mehrerer Klassen / Designpattern
OOP spielt sich hauptsächlich bei 5),6) und 7) ab.


zu 2.)
* ist dir aufgefallen, dass du Komponenten ganz einfach in "FMyList" packen kannst?
Delphi-Quellcode:
// Label erzeugen und an "FMyList" anhängen
lbl := TLabel.Create(FMyList {<== hier});
Einfacher geht's ja wohl nicht.
Dadurch das du FMylist als sogannten Owner (Besitzer) im Create angegeben hast,
landet das neue Label in FMyList.
* ist dir aufgefallen, dass du dir keinerlei Gedanken machen musst,
auf welcher Position das Label, Editfeld gespeichert wird?
Bei einem Array müsstest du a.) immer aufpassen dass das Array groß genug ist und b.)
immer mitzählen.
* ist dir aufgefallen, dass du deine Komponenten nirgends freigeben musst?
Weil FMyList dem Formular gehört wird FMyList und alles was darunter hängt AUTOMATISCH freigegeben.
Bei einen Array müsstest du in einer Schleife über alle Objekte gehen und jedes einzeln freigeben.

stahli 13. Okt 2010 18:03

AW: Object dynamisch in einem Array erzeufen
 
Um Deine Objekte nur in einer Liste zu speichern kannst Du im Grunde beides nutzen (ist quasi Geschmackssache).
Mit einer TList oder TObjectList ist es aber insgesamt komfortabler.

Arrays würde ich nur bei sehr kleinen Mengen oder im Gegenteil bei größeren, mehrdimensionalen Mengen nutzen.

Wenn eine Sammlung von Objekten gespeichert werden, bietet sich eine TObjectList ideal an.
Das geht so weit, dass beim Löschen eines Objekts aus der Liste dieses auch automatisch freigegeben werden kann.

...

Vielleicht verwirrt Dich das o.g. Beispiel der geschätzten Kollegen :wink: mit dem "FMyList" etwas... (könnte ich mir zumindest vorstellen).
"FMyList" ist von der Klasse TComponent.
Diese verwaltet wiederum intern eine Liste von allen Komponenten, die ihr untergeordnet sind.
Auf diese könnte man z.B. in einer Schleife auch zugreifen z.B. durch

Delphi-Quellcode:
  I: Integer;
  C: TComponent;
begin
  for I := 0 to MyList.ComponentCount - 1 do
  begin
    C := MyList.Components[I];
    C.TuWas;
  end;
end;
Du kannst jedoch auch eine "richtige" TList oder TObjectObjectList verwenden und dann direkt damit arbeiten.

Die Beizeichnung "FMyList" ist also vielleicht etwas verwirrend, da ja keine TList benutzt wird.

gangs-taas 13. Okt 2010 19:22

AW: Object dynamisch in einem Array erzeufen
 
hey,
noch einmal vielen dank für eure vielen antworten.
Leider muss ich zugeben, dass ich bei der Hälfte nur Bahnhof versteh.

z.B. was Templates sind versteh ich nicht wirklich. Bzw. nicht ihren nutzen
auf der einzigen deutschen Internetseite (diei ch gefunden hab) steht zu Templates : [QUOTE = http://www.dummzeuch.de/delphi/objec...tsch.html]Dies ist eine Klasse mit einem Array, die beim Zugriff ueberprueft, ob der Index innerhalb der Arraygrenzen liegt.[/QUOTE]
okay heißt ein Template hilft also bei einem Array keine Elemente anzusprechen, die nich existieren.

kann ich nicht einfach überprüfen, ob das Array Element existiert und fertig ?

von dem Code den David Martens auf der ersten seite gepostet hat versteh ich ehrlich gesagt fast nichts.

So dann habt ihr von der ObjectList gesprochen. Das hinzufügen sieht ja ganz einfach aus, aber ich finde wenn ich ein Elemt ansprechen will und dafür jedesmal
Delphi-Quellcode:
TKlasse(ObjectList.last).methode;
schreiben muss, ist das ganze irg. umständlich.

Das was David Martens geschriebne hat :

Zitat:

Zitat von David Martens (Beitrag 1055642)
Delphi-Quellcode:
  ObjectX := TObjectX.Create(...);
  ObjectXList := TObjectXList.Create(...);

  ObjectX.blabla := ....
  ...

  ObjectXList.Add(Object);

  ...
  ...

  ObjectXList.Items[i].blaba.....  (und nicht TObjectX(ObjectXList.Items[i]).blaba) oder
  ObjectXList[i].blaba.....        (und nicht TObjectX(ObjectXList[i]).blaba)

sieht ja wieder relativ einfach aus, aber wenn sich das immer noch auf Templates bezieht fürchte ich, dass ich damit nicht sonderlich viel machen kann, da ich die irg. nicht verstanden hab

Die Internetseite Link spricht davon, dass man TObjectList's so typisieren kann, dass man Elemente ähnlich Wie David M. das macht ansprechen kann.
Leider steht da auch nur ein haufen Code und keine Erklärung und ich versteh nicht wikrlich was sie wieso machen ...

Jens01 13. Okt 2010 19:43

AW: Object dynamisch in einem Array erzeufen
 
@David Martens
Ich wollt hier mal kurz in die Diskussion springen und sagen, dass dies Objectlist-Template eigentlich sehr gut funktioniert. :thumb:
Es sieht zwar etwas ungewöhnlich aus, da man dies Templete 2x geteilt in die Unit einfügen muß, ansonsten spart es viel Platz/ Code.
Ein Nachteil habe ich aber ausgemacht, man kann dies Template nur einmal in eine Unit einfügen. Wenn man mehrere Listen -der Code ist jetzt ja schön kurz- in einer Unit verarbeiten will, funktioniert das nicht -jedenfalls bei mir-.

Gruss Jens

Sir Rufo 13. Okt 2010 20:20

AW: Object dynamisch in einem Array erzeufen
 
Zitat:

Zitat von gangs-taas (Beitrag 1055648)
... was Tamplates sind versteh ich nicht wirklich

nur so am Rande es heißt Templates
Zitat:

Zitat von gangs-taas (Beitrag 1055648)
okay heißt ein Tamplate hilft also bei einem Array keine Elemente anzusprechen, die nich existieren.

Nein, das ist nur ein Beispiel wie man Templates verwenden kann
Zitat:

Zitat von gangs-taas (Beitrag 1055648)
So dann habt ihr von der ObjectList gesprochen. Das hinzufügen sieht ja ganz einfach aus, aber ich finde wenn ich ein Elemt ansprechen will und dafür jedesmal
Delphi-Quellcode:
TKlasse(ObjectList.last).methode;
schreiben muss, ist das ganze irg. umständlich.

Dafür nimmt man das Template von David Martens denn dann entfällt dieses umfudeln (nennt man Typecast)
Ohne Templates muss man halt den Typecast machen

Wenn du ein neueres Delphi hast (ab D2009) dann gibt es die Generics und da geht das dann ganz einfach
Delphi-Quellcode:
Type
  TFoo = class
   Data : string;
  end;

  TFooList = TObjectList<TFoo>;
Dieser Code ab D2009 bringt im Ergebnis den gleichen Effekt wie das Template von David Martens

Chemiker 13. Okt 2010 21:15

AW: Object dynamisch in einem Array erzeufen
 
Hallo,

die TList, TObectlist usw. arbeitet aber intern auch mit einem Pointer-Array.

Bis bald Chemiker

stahli 13. Okt 2010 21:21

AW: Object dynamisch in einem Array erzeufen
 
Also der arme gangs-taas tut mir leid.
Er wollte doch nur wissen, was sich für den Einstieg am einfachsten anwenden lässt...

David Martens 13. Okt 2010 22:17

AW: Object dynamisch in einem Array erzeufen
 
@Jens01: Das hab ich auch schon festgestellt.

@alle: Diese Art des Templates ist leider nicht auf meinem Mist gewachsen. Ich hab das Ganze nur leicht abgewandelt.

@gangs-taas:
Zitat:

http://www.dummzeuch.de/delphi/objec...tsch.html] Dies ist eine Klasse mit einem Array, die beim Zugriff ueberprueft, ob der Index innerhalb der Arraygrenzen liegt.
Da wird nur Bezug auf das obrige Beispiel genommen. Hier ein Link zum allgemeinen Thema Template http://de.wikipedia.org/wiki/Template_(Programmierung)

Mehr Hilfe als in Posting 13 kann ich kaum geben, aber ich versuchs mal:

Hier der ENTSCHEIDENDE Teil:
Delphi-Quellcode:
unit u_FilterItemList; /// /// 1. Anpassung ////// HIER ein sinnvoller Name für die Unit

interface

uses
  Classes,
  // Unit mit Klasse für _ITEM_TYPE_ (eine ganz normale Klasse)
  u_FilterItem; /// /// 2. Anpassung ////// HIER die Unit in dem das Objekt steht das die Liste soll

// Kompilerdirektive für das Template
{$DEFINE LIST_TEMPLATE_}

type
  // Vorfahr der "Listklasse"
  _LIST_ANCESTOR_ = TObject;
  // Vorfahr der "Kontainerklasse", sollte ein Nachfahr von TList sein
  _LIST_CONTAINER_ = TList;
  // Typ des Items in der "Kontainerklasse" (z.B.: Pointer für TList, IInterface für TInterfaceList}
  _LIST_CONTAINER_ITEM_TYPE_ = pointer;
  // Item der typisierten Klasse, dieser Typ wird von der Klasse ausgegeben
  _ITEM_TYPE_ = TFilterItem; /// /// 3. Anpassung ////// HIER das Objekt das aus der Unit (siehe 2. Anpassung) in die Liste soll

// Verzeichnis: \Delphi\Komponenten\Templates nicht in Umgebungsvariablen vorhanden daher so:

// 1. Template-aufruf: erstellt den Kopf der _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}  /// /// 4. Anpassung ////// HIER den Pfad anpassen wenn das Template wo anders ist

type
  // "Umbenennung" von _LIST_TEMPLATE_ und weitere spezielle Eigenschaften für die Klasse
  TFilterItemList = class(_LIST_TEMPLATE_) /// /// 5. Anpassung ////// HIER der ListenKlasse deinen Namen geben
  protected
    // muss implementiert werden, falls die Items freigegeben werden müssen (destructor Aufruf)
    procedure FreeItem(_Item: _ITEM_TYPE_); override;
  end;

implementation

// 2. Template-aufruf: implementiert die _LIST_TEMPLATE_ Klasse anhand der oben gemachten Angaben
{$INCLUDE '..\Templates\t_TypedObjectList.pas'}  /// /// siehe 4. Anpassung


// Implementierung der speziellen Eigenschaften der Klasse

{ TFilterItemList } /// /// siehe 5. Anpassung

procedure TFilterItemList.FreeItem(_Item: _ITEM_TYPE_); /// /// siehe 5. Anpassung
begin
  _Item.Free;

  inherited;
end;

end.
Alle entscheidenden Teile hab ich mit /// /// X. Anpassung bzw. /// /// siehe X. Anpassung markiert / zusätzlich kommentiert.

gangs-taas 13. Okt 2010 22:23

AW: Object dynamisch in einem Array erzeufen
 
Zitat:

Zitat von stahli (Beitrag 1055662)
Also der arme gangs-taas tut mir leid.
Er wollte doch nur wissen, was sich für den Einstieg am einfachsten anwenden lässt...

ist ja schön, dass du dich über mich lustig machst -.-
aber ich ziehe eine einfach lösung, die ich versteh, einer komplizierten, die ich per copy&past benutzen kann, vor

sorry wenn das hier auf unverständnis trifft

euch übrigen danke nochmal

@ David Martens :
danke ich glaub langsamm versteh ich es (zwar nicht alles & nicht warum) aber ich denk, ich kann esn utzen ...
danke

David Martens 13. Okt 2010 22:29

AW: Object dynamisch in einem Array erzeufen
 
@gangs-taas: Du mußt es ja auch nicht alles verstehen, nur die entscheidenden Stellen ändern :-D

stahli 13. Okt 2010 22:30

AW: Object dynamisch in einem Array erzeufen
 
Nee, sorry, da hast Du mich falsch verstanden!
Ich meinte das so, dass Du hier mit komplexen Lösungen bombardiert wirst. Ich hätte da als Anfänger schon aufgegegeben.

M.E. ist halt TObjectList mit einem TypeCast die einfachste und übersichtlichste Lösung.

Also ich meinte letztlich genau das:
Zitat:

aber ich ziehe eine einfach lösung, die ich versteh, einer komplizierten, die ich per copy&past benutzen kann, vor
Ich hoffe, dass das Missverständnis damit geklärt ist...

gangs-taas 13. Okt 2010 22:32

AW: Object dynamisch in einem Array erzeufen
 
Zitat:

Zitat von David Martens (Beitrag 1055671)
@gangs-taas: Du mußt es ja auch nicht alles verstehen, nur die entscheidenden Stellen ändern :-D

ookay :D
probier ich morgne
heute ist zu spät um vernünftig zu denken und zu ändern :D

gute nacht


ps
Zitat:

Zitat von stahli (Beitrag 1055672)
Nee, sorry, da hast Du mich falsch verstanden!
Ich meinte das so, dass Du hier mit komplexen Lösungen bombardiert wirst. Ich hätte da als Anfänger schon aufgegegeben.

M.E. ist halt TObjectList mit einem TypeCast die einfachste und übersichtlichste Lösung.

Also ich meinte letztlich genau das:
Zitat:

aber ich ziehe eine einfach lösung, die ich versteh, einer komplizierten, die ich per copy&past benutzen kann, vor
Ich hoffe, dass das Missverständnis damit geklärt ist...

okay
sorry ich hatte dich echt falsch verstanden
ja mir schwirrt der kopf :D
aber scheinbar muss man es nicht alles verstehn :D
ich versuchs morgne in ruhe nachzuvollziehen ...



danke für eure hilfe

Luckie 14. Okt 2010 00:16

AW: Object dynamisch in einem Array erzeufen
 
Wo wird hier was der Liste hinzugefügt:
Delphi-Quellcode:
   // dynamisch Komponenten erzeugen und in die Liste packen
   for i := 0 to 10 do
   begin
      lbl := TLabel.Create(FMyList {<==});
      lbl.Caption := Format('Label %d',[i]);
      lbl.Top := i * 15;
      lbl.Left := i * 9;
      lbl.Parent := Self;
   end;

schlecki 14. Okt 2010 07:22

AW: Object dynamisch in einem Array erzeufen
 
Zitat:

Zitat von Luckie (Beitrag 1055676)
Wo wird hier was der Liste hinzugefügt:
Delphi-Quellcode:
   
      lbl := TLabel.Create(FMyList {<==});

hier ;)

Gruß
schlecki

[edit]wurde aber auch schon in #14 erwähnt[/edit]

Luckie 14. Okt 2010 11:31

AW: Object dynamisch in einem Array erzeufen
 
Wird da nicht nur der Besitzer gesetzt?

Sir Rufo 14. Okt 2010 11:34

AW: Object dynamisch in einem Array erzeufen
 
Das wurde doch schon in #15 angesprochen

Luckie 14. Okt 2010 11:41

AW: Object dynamisch in einem Array erzeufen
 
Das ist der Schlüsselsatz:
Zitat:

Dadurch das du FMylist als sogannten Owner (Besitzer) im Create angegeben hast,
landet das neue Label in FMyList.
Danke für den Hinweis.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz