OOP4: Zeiger

Im Kopf eines Pascal-Programm werden folgende Typen und Variblen vereinbart:

type 
TDaten = array[1..100] of byte;
PDAten = ^TDaten;
TString = string[100];
PString = ^TSTring;


var
  a,b : TDaten;
  pa, pb : PDaten;
  s1,s2 : TString;
  ps1, ps2 : PString;

Mit diesen Deklarationen werden a,b, s1,s2 usw. bestimmte Speicherplätze zugeordnet, deren Adressen man sich mit   pa := addr(a) oder ps1 := addr(s1) anzeigen lassen kann. Bei den oben definierten Zeigern handelt es sich um sog. typisierte Zeiger, weil sie per Definition auf einen Speicherbereich zeigen, der von einem vorher definierten Datentyp belegt ist. Eine Zuweisung ps1 := pa ist deswegen natürlich nicht möglich.

Dagegen kann man durchaus zuweisen: ps1 := ps2. Allerdings wird dabei nur der Zeiger ps1 auf die Adresse ps2 'verbogen'. eine Wertezuweisung findet nicht statt. Die Zuweisung s1 := s2 kopiert den Speicherbereich, den s2 belegt in den von s1 belegten Speicherbereich.

Zeiger können auch dynamisch, d.h. während der Laufzeit angelegt werden. Mit der Anweisung new(ps1) erzeugt man auf dem Heap den entsprechenden Speicherplatz. Um diesen Speicherplatz mit bestimmten Werten zu füllen, benutzt man die Anweisung ps1^:= s1. Umgekehrt kann man den Speicherinhalt der bei ps1 beginnt, in die Variable s2 mittels s2 := ps1^ kopieren. Um reservierten Speicherplatz auf dem Heap wieder freizugeben, verwendet man die Anweisung dispose(s2).

Listen und andere Datenbehälter speichern Objekte mit Hilfe von untypisierten Zeigern auf das entsprechende Objekt. Das hat den grossen Vorteil, dass man verschiedenste Objekttypen in einer Liste gemeinsam speichern kann.  Außerdem braucht man nicht für jeden Datentyp einen eigenen Listentyp. In Delphi machen die Stringlisten eine Ausnahme. Sie können nur von Daten vom Typ string verwendet werden. Diese Einschränkung wird dadurch wieder gutgemacht, dass die Klasse TStringList einfache Methoden zum Speichern (SaveToFile), zum Laden (LoadFromFile) usw. zur Verfügung stellt.

Will man umgekehrt Objekte in eine Liste einfügen, muss man bedenken, dass Objektze immer als Zeiger behandelt werden, eine ausdrückliche Referenzierung ist also nicht nötig. I.a.W.: Man kann ein Objekt direkt in eine Liste einfügen: Liste1.Add(MeinObjekt1), ohne sich vorher einen typisierten Zeiger auf dieses Objekt verschaffen zu müssen.

Zum Auslesen der Objekte aus einer Liste muss der gespeicherte untypisierte Zeiger zunächst erst einmal in einen typisierten umgewandelt werden, z.B.:  pa := Liste1.Items[3]. Danach kann die Zuweisung a := pa^ erfolgen. 

Bei  Ereignisbehandlungen wird i.a. der Sender des Ereignis weitergegen, z.B. Button1.Onclick(Sender:TObject). Möchte man jetzt bei dem Handler auf bestimmte Eigenschaften des Senders zugreifen, muss man wieder eine Typisierung vornehmen. Das geschieht z.B. mit den Anweisungen:

Titel := TButton(Sender).Caption oder auch Titel := (Sender as TButton).Caption

Eine Typenüberprüfung kann man mittel der Anweisung if Sender is TButton vornehmen.

Das Programm adressen.pas enthält Beispiele für typisierte Zeiger, 7x5_display.pas für die o.e. Typenumwandlung.

Zurück zu Delphi

© Dietrich Praclik