Funktions- und Methodenzeiger
Funktionen und Prozeduren können selbst in Variablen gespeichert werden (bzw. ein Verweis auf sie). Somit ist es möglich, einer Funktion eine andere Funktion als Parameter zu übergeben.
type TMeineFunktion = function: Integer;
In diesem Fall haben die Funktionen oder Prozeduren keinen Namen, sondern bestehen aus dem Schlüsselwort function oder procedure, bei Bedarf gefolgt von Parametern in runden Klammern und einem Rückgabewert. Handelt es sich um Methoden, folgt noch „of object“:
TMeineMethode = procedure of object;
Praktischer Nutzen der Sache: Man kann somit eine Ereignisbehandlungsroutine erstellen und erst zur Laufzeit einem Objekt (einer Komponente) zuordnen.
Beispiel:
type TMyOnClick = procedure(Sender: TObject) of object; TMyForm = class(TForm) procedure MyButtonClickEvent(Sender: TObject); end; var MyOnClick: TMyOnClick; MyForm: TMyForm; ... MyOnClick := MyForm.MyButtonClickEvent;
Die OnClick-Events der Komponenten haben ebenfalls einen Methodenzeiger als Typ, den gleichen wie TMyOnClick im Beispiel. Deshalb ist es möglich, z.B. einem Button zur Laufzeit eine Methode mit dem gleichen Parameter zuzuweisen. Variablen vom Typ einer Funktion/Prozedur beinhalten die Speicheradresse, also einen Zeiger auf die Routine. Bei Methoden werden zwei Zeiger gespeichert: die Adresse der Methode und eine Referenz auf die Instanz.
Was ist ein Methodenzeiger? Genau genommen ist ein Methodenzeiger eine Referenz auf eine Methode einer Instanz einer Klasse. Das klingt jetzt erstmal kompliziert. Es handelt sich hierbei aber um das einfache „procedure() of object“. Ein solcher Methodezeiger kann jede Methode eines jeden Objekts aufnehmen, die dieselbe Signatur (Rückgabewert, Parameter) besitzt.
procedure SimulatedMethod(Self: TForm1; Sender: TObject); begin Self.Caption := 'Du hast mich aufgerufen'; end; procedure TForm1.FormCreate(Sender: TObject); var Event: TNotifyEvent; begin TMethod(Event).Code := @SimulatedMethod; TMethod(Event).Data := Self; Button1.OnClick := Event; end;
Mit dieser Technik kann man auch die Methode bzw. das Objekt austauschen.