Joh hat geschrieben: Do 10. Jul 2025, 12:10
Bisher war ich der Meinung, ein @setFilter entspricht einem Pointer auf die Funktion setFilter. Kann ich überhaupt die Prozedur übergeben?
Oder wäre der passendere Weg, im Construktor über AOwner.setFilter zu gehen?
Es gibt verschiedene arten von Funktionspointern die sich in Kontext unterscheiden. Reine Funktionspointer ohne Kontext zeigen einfach nur auf ein stück Code. Die haben prozeduren typen:
Code: Alles auswählen
type
TMyProcPointer = procedure(Arg: Integer);
TMyFuncPointer = function(Arg: Integer): Integer);
Dann gibt es Methodenpointer, die zeigen auf Methoden von Klassen. Eine Methode wird immer im Kontext eines Objektes aufgerufen, was man über Self referenzieren kann. Intern sind methoden pointer tatsächlich einfach 2 pointer, einer zum Code und einer zum Objekt:
Code: Alles auswählen
type
TMyProcMethodPointer = procedure(Arg: Integer) of object;
TMyFuncMethodPointer = function(Arg: Integer): Integer of object;
Und es gibt in Pascal noch nested Funktionen, das sind Funktionen im Kontext einer anderen Funktion, die können z.B. auf die Lokalen Variablen der umgebenden Funktion oder deren Parameter zugreifen. Ein Nested Funktionspointer enthält einen Pointer auf den Stack der umgebenden funktion, und den Pointer in den Code:
Code: Alles auswählen
type
TMyNestedProcPointer = procedure(Arg: Integer) is nested;
TMyNestedFuncPointer = function(Arg: Integer): Integer is nested;
Zu guter letzt gibts dann noch Funktions Referenzen, das sind Closures die ihren state in einem eigenen Objekt capturen. Intern sind das eigentlich einfach Objekte mit einer Invoke methode. Alle oben genannten funktionspointer typen können in eine Funktionsreferenz umgewandelt werden wobei der State zu dem Objekt hinzugefügt wird:
Code: Alles auswählen
type
TMyNestedProcPointer = reference to procedure(Arg: Integer);
TMyNestedFuncPointer = reference to function(Arg: Integer): Integer;
Die 3 basis funktionspointer (raw, method und nested) sind jeweils basisobjekte, im raw funktionspointer sind im Grunde Pointer und method und Nested sind im grunde ein Record mit 2 pointern.
Funktionsreferenzen erstellen eine instanz einer eigenen Klasse die auf dem Heap liegt, damit ist mit denen immer eine Memory Allokation verbunden und sie sind damit deutlich resourcen aufwendiger. Dafür vereinheitlichen sie alle drei konzepte und durch den State Capture als Closure bleibt der State auch über das lebensende der erstellenden Funktion erhalten.
PS: Anonymous Functions sind übrigens einfach nur nested procedures (wenn sie auf state zugreifen, sonst sogar raw), und sind daher entweder als nested(raw) funktionspointer oder funktionsreferenz darstellbar