Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi denkfehler; array-> dynarray (https://www.delphipraxis.net/127138-denkfehler%3B-array-dynarray.html)

Luckie 8. Jan 2009 15:35

Re: denkfehler; array-> dynarray
 
Hm, dann habe ich da ein grundlegendes Verständnisproblem, was die Collection angeht. Weil ich sehe nicht, wie ein Objekt in die Liste kommt bzw. ... warte ... ich sehe irgendwas im Nebel schimmern...kann es aber nicht fassen.

Könntets du mir mal bitte eben erklären, wie die TCollection funktioniert? Interessiert wahrscheinlich auch den Threadersteller.

guidok 8. Jan 2009 15:51

Re: denkfehler; array-> dynarray
 
Ehrlich gesagt bin ich mir nicht sicher, ob ich das erklären kann, aber ich versuche es.

Die Collection ist im Prinzip so ähnlich wie eine ObjectList, d.h. du kannst Objekte darin speichern. Allerdings müssen diese Objekte von TCollectionItem abgeleitet werden und pro Collection geht nur ein Objekttyp.

Also in dieser Reihenfolge:

1. Ein Objekt mit den gewünschten Eigenschaften/Methoden von TCollectionItem ableiten.
2. Eine Collection von TCollection ableiten und der Bequemlichkeit halber bereits hier die entsprechenden Typcasts auf den Itemtypen vornehmen. Zusätzlich können hier natürlich auch noch Methoden und Eigenschaften, die die gesamte Collection betreffen programmiert werden (z.B. um bei den Viechern zu bleiben, eine "Mutiere"-Methode, die durch alle Viecher in der Collection iteriert und deren Mutieren Methode aufruft).
3. Die Collection mit Daten füllen (Add, Insert) oder die Daten in der Collection bearbeiten (Delete).

Den Punkt 2 könntest du auch weglassen, dann musst du die Typcasts halt beim Aufruf der ursprünglichen Methoden machen. Ich nehme mal die Viecher als Beispiel her und gehe davon aus, dass Collection einfach vom Typ TCollection ist.

Delphi-Quellcode:
var tempViech: TViech;

tempViech := TViech(Collection.Add);

//So sieht übrigens das Create von TCollection intern aus
constructor TCollection.Create(ItemClass: TCollectionItemClass);
begin
  FItemClass := ItemClass;
  FItems := TList.Create;
  NotifyDesigner(Self, Self, opInsert);
end;

//und so die Add Methode
function TCollection.Add: TCollectionItem;
begin
  Result := FItemClass.Create(Self);
  Added(Result);
end;
Ich schreib auch gleich das Beispiel aus Punkt 2 hin, bevor Fragen kommen. "Mutieren" aller Viecher:
Delphi-Quellcode:
procedure TViecher.Mutiere;
  var i: Integer;
begin
  for i := 0 to Count - 1 do begin
    Viech[i].Mutiere;
  end;
end;

//Im Hauptprogramm ruft man jetzt nur noch eine Methode auf und Mutiert alle Viecher
BlaueViecher.Mutiere;

vsilverlord 10. Jan 2009 14:59

Re: denkfehler; array-> dynarray
 
Das mit der Collection sieht gut aus.
2 Fragen:
1. Ist die Anzahl der möglichen Viecher höher oder niedriger wie bei dem array, was ist der vorteil zum array [außer dass es eleganter ist und besser aussieht]
2. kann ich auch kollektion einer kollektion bilden? also angenommen, ich möchte alle viecher verändern, aber den Forschritt festhalten, in dem ich alle Versionen des Viechs habe?
z.b
[1]
viech[1].haare=1 -> mutiere
viech[2].haare=2 -> mutiere
viech[3].haare=3
[2] verändere alle viecher [+1]
viech[1].haare=2 -> mutiere
viech[2].haare=3 -> mutiere
viech[3].haare=4
[3] verändere alle viecher [+2]
viech[1].haare=4 -> mutiere
viech[2].haare=5 -> mutiere
viech[3].haare=6

meiner ansicht wäre das mit zweierlei varianten möglich, also einmal die collection als array, oder die collection als collection einer collection.
:drunken:

jfheins 10. Jan 2009 15:28

Re: denkfehler; array-> dynarray
 
Die Zahl der Viecher dürfe groß sein (Durch den Heap begrenzt)

Du kannst Collections verschachteln. Also in einem CollectionItem wieder eine Collection drin haben.

Es reicht ein Collection.SaveToFile(...); Um alles zu speichern (inkl. published Properties und Sub-Collections)

Siehe auch Hier im Forum suchendpCollection und http://www.delphipraxis.net/internal...ct.php?t=62023 ;)

vsilverlord 10. Jan 2009 15:32

Re: denkfehler; array-> dynarray
 
wie schreib ich da den type? mit den properties= so vllt?
Delphi-Quellcode:
type
  TViecher = class(TCollectionitem)
  protected
    function GetViech(Index: Integer): TViech;
    procedure SetViech(Index: Integer; Value: TViech);
  public
    function Add: TViech;
    function Insert(Index: Integer) : TViech;
    property Viech[Index: Integer]: TViech read GetViech write SetViech; default;
  end;
...
type
  TViechergruppe = class(TCollection)
  protected
    function GetViecher(Index: Integer): TViecher;
    procedure SetViecher(Index: Integer; Value: TViecher);
  public
    function Add: TViecher;
    function Insert(Index: Integer) : TViecher;
    property Viecher[Index: Integer]: TViech read GetViecher write SetViecher; default;
  end;

jfheins 10. Jan 2009 15:40

Re: denkfehler; array-> dynarray
 
Jetzt mal was aus dem Tutorial kopiert:

Delphi-Quellcode:
TmxCustomItem = class(TCollectionItem)
private
fStringItem: String;
public
procedure Assign(Source: TPersistent); overide;
published
property StringItem: String read fStringItem write fStringItem;
end;

(*
Dies ist eine normale Itemklasse, doch jetzt kommt der Unterschied zu einer herkömmlichen
Collection. Direkt nach der Item-Deklaration schreiben wir folgendes:
*)

{$define TYPED_DP_COLLECTION_TEMPLATE}
_COLLECTION_ITEM_ = TmxCustomItem;
{$INCLUDE dpCollection_tmpl.pas}
TTypedCollection = _COLLECTION_;
So einfach kann das gehen ;)

vsilverlord 10. Jan 2009 16:35

Re: denkfehler; array-> dynarray
 
ich hab jetzt noch nich ganz verstanden, was das bring:
Delphi-Quellcode:
{$define TYPED_DP_COLLECTION_TEMPLATE}
_COLLECTION_ITEM_ = TmxCustomItem;
{$INCLUDE dpCollection_tmpl.pas}
TTypedCollection = _COLLECTION_;

jfheins 10. Jan 2009 17:05

Re: denkfehler; array-> dynarray
 
Da Delphi keine Generics unterstütz(te) passiert folgendes:

In der Mitte wird die templae Datei mittels $Include eingebunden.

In der Datei wird eine typisierte Collection von dem Typ "_COLLECTION_" erstellt, die genau auf den Typ "_COLLECTION_ITEM_" abgestimmt ist. Dadurch brauchst dcu später nicht mehr casten.

Jetzt definiertst du erstmal deine Klasse. Anschließend gibst du ihr den Alias "_COLLECTION_ITEM_" ;)

Jetzt wird das Template eingebunden, das zu dieser Klasse eine Collection definiert. Danach erzeugst du wieder einen Alias für die Collection.

Ein Alias ist ein anderer Name für den selben Typen. Du kannst also über 2 Namen auf den gleichen Typ zugreifen ;)

guidok 11. Jan 2009 09:46

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von vsilverlord
Das mit der Collection sieht gut aus.
2 Fragen:
1. Ist die Anzahl der möglichen Viecher höher oder niedriger wie bei dem array, was ist der vorteil zum array [außer dass es eleganter ist und besser aussieht]
2. kann ich auch kollektion einer kollektion bilden? also angenommen, ich möchte alle viecher verändern, aber den Forschritt festhalten, in dem ich alle Versionen des Viechs habe?

Was ist der Vorteil? Naja, zunächst mal ist das eine elegante objektorientiere Programmierung. Die bringt dir natürlich auch den Vorteil, dass du dein Viech nur an einer Stelle (Deklaration von TViech) ändern musst und alle Viecher die Änderung mit machen. Allerdings, das sollte man nicht verschweigen, wird der Speicherbedarf wahrscheinlich etwas höher ausfallen (und noch höher, wenn du noch alle Vichversionen mit führen willst.) als bei einem Array.

Zur zweiten Frage. Das habe ich noch nicht probiert, aber im einfachsten Fall ist es so, dass du einfach im TVich noch eine Collection einbaust. Dabei sieht TViechVersion (TCollectionItem) und TViecherVersion(TCollection) im Prinzip genau so aus, wie TViech und TViecher bisher aussahen. Du kannst da natürlich die Methoden zum Mutieren weglassen, weil du nur Daten darin sichern willst.

Delphi-Quellcode:
type
  TViech = class(TCollectionItem)
  private
    FLaenge: Real;
    FHaare: Real;
    FVersion: TViecherVersion;
    //..weitere Eigenschaften
  public
    constructor Create(Collection: TCollection); override;
    procedure Mutiere;
    procedure Assign(Source: TPersistent);
    //..weitere Methoden
    property Laenge: Real read FLaenge write FLaenge;
    property Haare: Real read FHaare write FHaare;
    property Version: TViecherVersion read FVersion write FVersion;
    //..weitere Eigenschaften
  end;
nicht vergessen im Constructor:
Delphi-Quellcode:
  FVersion := TViecherVersion.Create(TViechVersion);
und dazu brauchst du dann noch im Destructor:
Delphi-Quellcode:
  FVersion.Free;
Die Methode "Mutiere" von TViech könnte dann so aussehen:
Delphi-Quellcode:
procedure TViech.Mutiere;
  var tempVersion: TViechVersion;
begin
  tempVersion := Version.Add;
  tempVersion.Assign(self); //Die aktuelle Version des Viechs zuweisen, bin nicht sicher, ob das so klappt

  //Eventuell könnte auch dies funktionieren, dann braucht man keine tempVersion -> probieren!
  Version.Add.Assign(self);
 
  //und jetzt wird fröhlich mutiert
  Laenge := //irgendwas;
  Haare := //irgendwas;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:33 Uhr.
Seite 5 von 5   « Erste     345   

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