Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie Array mit Pointern auf Klassen-Instanzen füllen? (https://www.delphipraxis.net/18875-wie-array-mit-pointern-auf-klassen-instanzen-fuellen.html)

Nonsense 25. Mär 2004 16:21


Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Hallo Community,

ich möchte gerne ein Array of Pointer mit Zeigern auf Klassen-Instanzen füllen. Leider klappt das bei mir nicht so ganz.
Ich habe als erstes meine Klasse mit dem Array of Pointer:
Delphi-Quellcode:
  TWorld = class
  private
    [ ... ]
    FBufferArray: array of array of Pointer;
  public
    constructor Create(WorldHeight, WorldWidth: Integer);
    [ ... ]
  end;
Und dann noch eine andere Klasse TGround. Jetzt möchte ich in den contructor eine Schleife, die dass komplette Array mit Zeigern auf TGround-Instanzen füllt. D.h. ich müsste in der Schleife die Instanzen auch erstellen. Aber wie mache ich das? Ich kann ja schließlich nicht sowas wie
Delphi-Quellcode:
  for i := 0 to FWorldHeight do
    for j := 0 to FWorldWidth do
    begin
      FBufferArray[i][j] := new(TGround.Create);
    end;
schreiben.

Hat jemand eine Idee?

Danke im Voraus.

MfG

neolithos 25. Mär 2004 16:28

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Wie wäre es damit...

Delphi-Quellcode:
  TWorld = class
  private
    [ ... ]
    FBufferArray: array of array of TCreatur;
  public
    constructor Create(WorldHeight, WorldWidth: Integer);
    [ ... ]
  end;
Delphi-Quellcode:
  SetLength(fBufferArray, FWorldHeight);
  for i := 0 to FWorldHeight - 1 do
    for j := 0 to FWorldWidth - 1 do
    begin
      SetLength(fBufferArray[i], FWorldWidth);
      FBufferArray[i][j] := TGround.Create;
    end;

Nonsense 25. Mär 2004 16:30

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
@neolithos: Geht leider nicht, da meine TGround Klasse nur ein Beispiel ist. Wenn das ganze läuft, sollen da Pointer von 4 verschiedenen Klassen in das Array rein. Deshalb ja auch das Array of Pointer, da ich ja sonst nicht 4 verschiedene Klassen in einem Array speichern kann.

neolithos 25. Mär 2004 16:34

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Dann tausche TGround durch TObject.

Das ist "so eine Art" Pointer für Klassen, denn wie ich verstanden habe sind es ja 4 Klassen.

shmia 25. Mär 2004 16:37

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

FBufferArray: array of array of Pointer;
Das geht sowieso nicht!
Es darf höchsten eine Dimension offen bleiben.
Also etwa:
array[1..100] of array of Pointer

Der Datentyp Pointer ist auch Falsch.
Da alle Klasse in Delphi von TObject abgeleitet sind wäre TObject der richtige
Datentyp.

Angenommen du möchtest ein 2-dim. Array mit offenen Grenzen.
Dann muss das mehrdimensionale Array auf das eindimensionale Array abgebildet
werden.

Delphi-Quellcode:
type
   TMeinObjArray = array of TObject; // offenes eindim. Array von Objekten

   maxX := 100; // zur Laufzeit festlegen
   maxY := 50;

// Speicher besorgen
   SetLength(meinObjArray, maxX*maxY);

// befüllen mit Instanzen
   for i:= 0 to maxY-1 do
      for j := 0 to maxX-1 do
         // da beide Dimensionen offen sind
         // müssen wir selber rechnen
         meinObjArray[i*maxX+j] := TGround.Create;

// Zugriff auf TGround an Position 13, 40
   TGround(meinObjArray[13*maxX+40]).LiftUpTotheSky(....);


// Instanzen freigeben
   for i := 0 to maxX*MaxY-1 do
   begin
      TGround(meinObjArray[i]).Free;
   end;
Schau dir mal TObjectList an; das könnte dir nützlich sein.

Nonsense 25. Mär 2004 16:37

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Dann tausche TGround durch TObject.

Das ist "so eine Art" Pointer für Klassen, denn wie ich verstanden habe sind es ja 4 Klassen.

Hatte mein Problem mal vor ein paar Wochen beschreiben, kannst ja mal gucken:
http://www.delphipraxis.net/internal...ct.php?t=19802

Meine Idee war damals, dass ich ein Array of TOberklasse erstelle und dann die verschiedenen Unterklassen welche sich von TOberklasse ableiten in der Array speichere. Nur hatte das irgendwie nicht hingehauen.

Naja, und ich dache mir das jetzt so:
1. Instanz von einer der Unterklassen erstellen (z.B. TGround, TGrass, etc.)
2. Pointer der Instanz im Array speichern

neolithos 25. Mär 2004 16:45

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Ich habe oben noch ein paar kleine Änderungen vorgenommen.

Warum soll das nicht gehen?
Gibt es Laufzeit bzw. Compilerer fehler.

Übrigens

TObject.Create liefert einen Zeiger auf das neue Object. Ich weiß nicht was das mit NewInstance soll.

Nonsense 25. Mär 2004 16:59

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Ich habe oben noch ein paar kleine Änderungen vorgenommen.

Warum soll das nicht gehen?
Gibt es Laufzeit bzw. Compilerer fehler.

Übrigens

TObject.Create liefert einen Zeiger auf das neue Object. Ich weiß nicht was das mit NewInstance soll.

Bei
Delphi-Quellcode:
  FBufferArray[i][j] := TGround.Create;
bekomme ich eine Zugriffsverletzung.

neolithos 25. Mär 2004 17:02

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
So jetzt probier ich es mal selber!

>>> Gedult!

Nonsense 25. Mär 2004 17:06

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
So jetzt probier ich es mal selber!

>>> Gedult!

:wink: 8)

neolithos 25. Mär 2004 17:11

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Delphi-Quellcode:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, PWLists, ComCtrls, CommCtrl;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    fEdits : array of array of TObject;
  public
    procedure CreateEdits(aiWidth, aiHeight : Integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateEdits(10, 10);
end;

procedure TForm1.CreateEdits(aiWidth, aiHeight: Integer);
var i,
    j : Integer;
begin
  LockWindowUpdate(Handle); // hat nix mit Array zu tun

  SetLength(fEdits, aiHeight);
  for i := 0 to aiHeight - 1 do
      begin
        SetLength(fEdits[i], aiWidth);
        for j := 0 to aiWidth - 1 do
            begin
              fEdits[i, j] := TEdit.Create(Self);
              with fEdits[i, j] as TEdit do
                begin
                  Parent := Self;
                  SetBounds(34 * j + 16, 25 * i + 16, 30, 21);
                  Text := Format('%d, %d', [i, j]);
                end;
            end;
      end;

  LockWindowUpdate(0);
end;

end.

Nonsense 25. Mär 2004 17:16

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Hier mal meins.

Die Klassen:
Delphi-Quellcode:
  TWorld = class
  private
    FWorldHeight: Integer;
    FWorldWidth: Integer;
    FBufferArray: array of array of TCreature;
    FWorldArray: array of array of TCreature;
  public
    constructor Create(WorldHeight, WorldWidth: Integer);
    destructor Destroy; override;
  end;

  TCreature = class
  private
    FName: string;
  public
  end;

  TGround = class(TCreature)
  private
  public
  end;

  TSand = class(TGround)
  private
  public
    constructor Create;
    destructor Destroy;
  end;
Und hier die Klasse TSand:
Delphi-Quellcode:
constructor TSand.Create;
begin
  inherited Create;

  FName := 'Sand';
end;
Sowie die Klasse TWorld:
Delphi-Quellcode:
constructor TWorld.Create(WorldHeight, WorldWidth: Integer);
var
  i: Integer;
  j: Integer;
  ArrayLength: Integer;
begin
  FWorldHeight := WorldHeight;
  FWorldWidth := WorldWidth;

  ArrayLength := WorldHeight * WorldWidth;
  SetLength(FBufferArray, ArrayLength);
  SetLength(FWorldArray, ArrayLength);

  for i := 0 to FWorldHeight - 1 do
    for j := 0 to FWorldWidth - 1 do
    begin
      FBufferArray[i][j] := TGround.Create;
    end;
end;

neolithos 25. Mär 2004 17:26

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Und hier meine korrekturen

Delphi-Quellcode:
constructor TWorld.Create(WorldHeight, WorldWidth: Integer);
var
  i: Integer;
  j: Integer;
  ArrayLength: Integer;
begin
  FWorldHeight := WorldHeight;
  FWorldWidth := WorldWidth;

  SetLength(FBufferArray, WorldHeight, WorldWidth);
  SetLength(FWorldArray, WorldHeight, WorldWidth);

  for i := 0 to FWorldHeight - 1 do
    for j := 0 to FWorldWidth - 1 do
    begin
      FBufferArray[i][j] := TGround.Create;
    end;
end;
Versuch es mal so

Nonsense 25. Mär 2004 17:39

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Und hier meine korrekturen
[ ... ]
Versuch es mal so

Neeeein! Verdammte Sche*ße nochmal. Wieso bin ich nicht darauf gekommen *handandenkopfklatsch*
Ich danke dir! :drunken:

Nonsense 25. Mär 2004 18:17

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Letzt Frage (wirklich! :wink: ):

Wie kann ich jetzt auf Variablen im Array zugreifen, ich meine:
Delphi-Quellcode:
TCreature = class
private
  FName: string;
public
end;

constructor TSand.Create;
begin
  inherited Create;

  FName := 'Sand';
end;

// ---------------------------------

  for i := 0 to FBlockNumX - 1 do
    for j := 0 to FBlockNumY - 1 do
    begin
      FBufferArray[i][j] := TSand.Create;
      FWorldArray[i][j] := TSand.Create;
    end;

// ---------------------------------
// Undeclared indetifier!
  if FWorldArray[i][j].FName := 'Sand' then ...;
Wo liegt der Fehler?

neolithos 25. Mär 2004 18:29

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Du musst noch das Private Element FName veröffentlichen.
Delphi-Quellcode:
TCreature = class
private
  FName: string;
public
  property Name : String read fName;
end;

Nonsense 25. Mär 2004 18:34

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Du musst noch das Private Element FName veröffentlichen.
Delphi-Quellcode:
TCreature = class
private
  FName: string;
public
  property Name : String read fName;
end;

Nääd, meine Fresse, bin ich heute schon wieder verpeilt...Ja, hat sich erledigt, du hast Recht...Wo bin ich bloß mit meinen Gedanken?

Nonsense 25. Mär 2004 18:43

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Klappt soweit, aber ich würde gerne eine Funktion schreiben, die den Namen zurückgibt. Dazu ein Frage: Wie kann ich die Instanz bei FWorldArray[x][y] per als Zeiger übergeben?
Habe sowas unter Object Pascal noch nie gemacht.

Muss ich da einen Pointer übergeben oder einen Pointer auf TCreature? (d.h. übergebe ich "PCreature: Pointer" oder "PCreature: ^TCreature"?).

neolithos 25. Mär 2004 18:46

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Delphi-Quellcode:
function GetName(fCreatur : TCreatur) : String;
begin
  Result := 'Name: ' + fCreatur.Name;
end;

Nonsense 25. Mär 2004 18:52

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Ich dachte mir das so:
Delphi-Quellcode:
function TCreature.GetName(PCreatur : TCreatur): string;
begin
  Result := PCreatur.FName;
end;

[...]

if MyCreature.GetName(^FWorldArray[i][j]) = 'Sand' then ...
Naja, vielleicht hänge ich bei dieser Geschichte auch zu sehr an C++ ... :wink:

Edit: Wieso kann ich keine Stile im Delphi-Code nutzen!?

neolithos 25. Mär 2004 18:57

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Delphi-Quellcode:

TCreature = class
private
  FName: string;
  function GetName(fCreatur : TCreatur): string;
public
  property Name : String read GetName;
end;

function TCreature.GetName(fCreatur : TCreatur): string;
begin
  Result := fCreatur.FName;
end;

[...]

if MyCreature.GetName(FWorldArray[i][j]) = 'Sand' then ...
Das ^-Zeichen kannst du dir bei Klassen in Delphi sparen. Es wird implizit angenommen.

neolithos 25. Mär 2004 18:58

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von Nonsense
Edit: Wieso kann ich keine Stile im Delphi-Code nutzen!?

Was meinst du damit?

Nonsense 25. Mär 2004 19:03

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Meine Idee macht ja eigentlich auch keinen Sinn, dass ganze in eine Funktion auszulagern, da ich dafür ja extra eine Instanz von TCreature erzeugen müsste.
Danke trotzdem. :dp:

Nonsense 25. Mär 2004 19:04

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Zitat:

Zitat von Nonsense
Edit: Wieso kann ich keine Stile im Delphi-Code nutzen!?

Was meinst du damit?

Na dass ich Fettschrift usw. einfüge.
Delphi-Quellcode:
[b]Funktioniert nicht[/b]

neolithos 25. Mär 2004 19:10

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Weil das sonst andere verwirren könnte.

es gibt da auch noch den pre-Tag

Code:
[b]Hallo Welt[/b]

Nonsense 25. Mär 2004 19:11

Re: Wie Array mit Pointern auf Klassen-Instanzen füllen?
 
Zitat:

Zitat von neolithos
Weil das sonst andere verwirren könnte.

es gibt da auch noch den pre-Tag

Code:
[b]Hallo Welt[/b]

Gut zu wissen. :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 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 by Thomas Breitkreuz