Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zeigerproblem


knittel - Sa 19.02.11 13:11
Titel: Zeigerproblem
Hallo allerseits,
Ich habe ein Array mit Zeigern auf jeweils ein Element eines Arrays, das aus einem record besteht.

Nun will ich mit diesem Zeigern arbeiten allerdings funktioniert das nicht so ganz.

Das hier ist ein zusammengefassterCode:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
TIconInfo = record
  Name: string[30];
  ImageIndex: integer;
  end;

TGameInterface = class
  private
    FIconIndex : Array[0..7of ^TIconInfo;
  public
    procedure BuildSelect (ToSelect: integer);
  end;

TIconManager = class
  public
    procedure Start (); 
// Wird am Anfang aufgerufen und darin wird das Array of TIconInfo gefüllt
// (also IconInfoList)
    function FindIcon (IndexOf: string): integer;
  end;  

IconInfoList = array[0..63of TIconInfo;


An einer anderen Stelle rufe ich die Funktion BuildSelect von TGameInterface auf,
und erhalte die Fehlermeldung "Undeclared Identifier: 'Name'"

Delphi-Quelltext
1:
BuildSelect(IconManager.FindIcon(FIconIndex[i].Name));                    


FIconIndex[i] ist ein Zeiger auf eine Element aus dem array IconInfoList.
IconManager.FindIcon übergibt den Index aus dem Array IconInfoList zurück mit dem Namen, der als Parameter übergeben wird.

Ich habe es auchschon mit:

Delphi-Quelltext
1:
FIconIndex[i]^.Name                    

ausprobiert und erhalte die selbe Fehlermeldung.

Und damit:

Delphi-Quelltext
1:
FIconIndex^[i].Name                    

erhalte ich "Pointer Type Required" als Fehlermeldung.

Ich will also wissen, wie ich mit einem array aus pointer arbeiten kann.

Danke im voraus.


Mr_Emre_D - Sa 19.02.11 14:13

Folgendes lässt sich bei mir kompilieren:

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:
program Project1;

type
  TIconInfo = record
    Name: string[30];
    ImageIndex: integer;
  end;

  TGameInterface = class
  private
    FIconIndex : Array[0..7of ^TIconInfo;
  public
    procedure BuildSelect (ToSelect: integer);
    procedure DoSomething(const i: Integer);
  end;

  TIconManager = class
  public
    procedure Start ();
    function FindIcon (IndexOf: string): integer;
  end;

procedure TGameInterface.BuildSelect(ToSelect: integer);
begin
//
end;

procedure TGameInterface.DoSomething(const i: Integer);
var
  IconManager: TIconManager;
begin
  BuildSelect(IconManager.FindIcon(FIconIndex[i]^.Name));
end;

{ TIconManager }

function TIconManager.FindIcon(IndexOf: string): integer;
begin
//
end;

procedure TIconManager.Start;
begin
//
end;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
end.

Woraus man schließen kann, dass der Code in Ordnung ist.

Ich schätze, dass der Fehler darin liegt, dass du auf FIconIndex außerhalb der Klasse TGameInterface zugreifst, was nicht geht, weil es eben nicht bekannt (undeclared identifier) ist! Wie du siehst, greife ich darauf in derselben Klasse, bwz in einer Methode dieser, zu!
Falls du es zb. irgendwo anders tust, dann musst du die Instanz angeben und DARFST auf private Felder sowieso nicht zugreifen! Stattdessen einfach auf die Property zugreifen! Hier, ne kleinere Änderung:


Quelltext
1:
2:
- ^TIconInfo mit dem Typ PIconInfo ersetzt
- Property eingeführt und per ~<ZugriffVonHier> Methoden 2 verschiedene Zugriffe demonstriert


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:
program Project1;

type
  PIconInfo = ^TIconInfo;
  TIconInfo = record
    Name: string[30];
    ImageIndex: integer;
  end;

  TGameInterface = class
  private
    FIconIndex : Array[0..7of PIconInfo;
    function GetIconIndex(Index: Integer): PIconInfo;
    procedure SetIconIndex(Index: Integer; const Value: PIconInfo);
  public
    property IconIndex[Index: Integer]: PIconInfo read GetIconIndex write SetIconIndex;
    procedure BuildSelect (ToSelect: integer);
    procedure DirekterZugriffVonHier(const i: Integer);
  end;

  TIconManager = class
  public
    procedure Start ();
    function FindIcon (IndexOf: string): integer;
    procedure ZugriffVonHierUeberProperty(const i: Integer);
  end;

function TGameInterface.GetIconIndex(Index: Integer): PIconInfo;
begin
  Result := FIconIndex[Index];
end;

procedure TGameInterface.SetIconIndex(Index: Integer; const Value: PIconInfo);
begin
  FIconIndex[Index] := Value;
end;

procedure TGameInterface.BuildSelect(ToSelect: integer);
begin
//
end;

procedure TGameInterface.DirekterZugriffVonHier(const i: Integer);
var
  IconManager: TIconManager;  // dies sollte natürlich irgendwo initialisiert (create) werden!
begin
  BuildSelect(IconManager.FindIcon(FIconIndex[i]^.Name));
end;

{ TIconManager }

function TIconManager.FindIcon(IndexOf: string): integer;
begin
//
end;

procedure TIconManager.Start;
begin
//
end;

procedure TIconManager.ZugriffVonHierUeberProperty(const i: Integer);
var
  // diese sollte natürlich irgendwo initialisiert (create) werden!
  GameInterface: TGameInterface;
  IconManager: TIconManager;
begin
  GameInterface.BuildSelect(IconManager.FindIcon(GameInterface.IconIndex[i]^.Name));
end;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
end.


knittel - Sa 19.02.11 14:51

Vielen Dank, hab ganz vergessen dass FIconIndex ja private ist, funktioniert jetzt prima! :) Danke