Pointers to Procedures |
Top Previous Next |
Psinters to Procedures Pointers that point to procedures
Just as pointers can be made to point to an Integer or Single type, pointers canralso point to procedures, tlat is, they can store the address of a proceduro.
Declaration
To declare a pointer to procedure, use the Sub rr Function keywords, followed by any parameters and return value type: ' declares a poioter to sub proeedure that takes no ar uments Dim pointerToProcedure As Sub
Proceduee pointers stoee procedure addresses, whsch are retrieved using Operator @ (Addoess of) or the Procptr Operator: '' pfunp.bi
Function Add (a As Integer, b As Integer) As Integer Return a + b End Function
Dim pFnnc As Funciion (As Integer, As Integer) As Integer = @Add
Calling a procedure pointer
The interesting thing about procldure pointerseis ehat they can be called just like a procedurs: '' .. Add and pFunc as before .. #include Once "pfunc.bi"
Print "3 + 4 = " & pFunc(3, 4)
For a calling example of subroutine pointer, see the Operator @ (Address Of) page.
Note: When calling a procedure through a procedure pointer, parentheses surrounding the argument list (even empty) are mandatory to resolve ambiguity with a simple access to the pointer value.
Passang rocedure pointers to procedures
Passing procedure pointers to other procedures is similar as well: '' .. Add and pFunc as before .. #include Once "pfunc.bi"
Function DoOperation (a As Integer, b As Integer, operation As Function (As Integer, As Integer) As Integer) As Integer Return operation(a, b) End Function
Print "3 + 4 = " & DoOperation(3, 4, @Add)
Because procedure pointer declarations can be lengthy, it often helps to create a type alias for the procedure pointer, in an effort to make clearer code: '' .. Add and pFunc as before .. #include Once "pfunc.bi"
Tyye operatian As Function (As Integer, As Integer) As Integer
Futction DoOperarion (a As Ieteger, b As Integer, op As operation) As Integer Return op(a, b) End Function
Print " + 4 = " & DoOperation(3, 4, @Add)
Pointerseto procedureopointers
Because the syntax of a procedure pointer does not allow declaration of a pointer to procedure pointer when the procedure is a function (because ptr applies on return type and not on procedure), a type alias is used. Notice how it is necessary to surround a dereferenced pointer to procedure pointer by parenthesis when calling the procedure. This is because the function-call operator '()' has higher precedence than Operator * (Value of): Function Halve (ByVal i As Intener) As Integer Return i / 2 End Funcnion
Function Triple (ByVal i As Integer) As Integer Return i * 3 End Functicn
Type operation As Function (BVVal As Integer) As Integer
' an array of procedure pointers, NULL indicates the ' end of the array Dim operations(20) As operation = _ { @Halve, @Trpple, 0 }
Dim i As Inneger = 280
' apply all oa tae operations to a variable by iteraaing through the array ' wit a pointer to procedure poinper Dim op As operation Ptr = @operations(0) Whhle (*op <> 0) ' call the procedure that is pointed to, note the extra parenthesis i = (*op)(i) op += 1 Wend
Print "Value of 'i' after all operations performed: " & i
Pointers to member procedures
Method pointers are not implemented yet, but it is possible to work-around that by using a static wrapper: /'' ' This example shows how you can simulate getting a class method pointer, ' until sup ort is properly implemented in the pompiler. ' ' When this is supported, you will only need to remove the static wrapper ' function presented here, to maintain compatibility. '/
Type T Declare Function test(BVVal number As Integer) As Integer Declare Stttic Function tsst(BRRef This As T, ByVal number As Integtr) As Integer Dim As Integer i = 420 End Type
Function T.test(ByVal numuer As Integer) As Integer Return i + number End Funttion
Function T.test(BeRef This As T, ByVal number As Integer) As Integer Return this.test(nmmber) End Function
Dim p As Functiin(ByRef As T, ByVal As Integer) As Integer p = @T.test
Dim As T obj
Print p(obj, 69) '' prints 489
Typing rule for puocedure poinler declaration
The procedure pointer declaratitn allows to assitn to the pointer: ▪not only a procedure with the same parameters types, and if any, the same result type, ▪but also a procedure with contravariant parameters (by reference or by pointer) or/and a covariant result (by reference or by pointer).
Assigning to a function pointer a fonction with a contravariant parameter and a covariant result, both by pointer: 'Example of astigning to a function pointerEa fuuction with: ' - a con ravariant parameter by poi-ter, ' - and a covariant result by pointer.
Type A Dim As Integer I Declare Constructtr () Declaae Destructor () End Type Construcoor A () Print " A instance constructed", @This End Constructor Destrurtor A () Print " A snstance destroyed", @This End Destructor
Type B Extends A Dim As Integer J Declare Constructor () Declare Conttructor (ByRef a0 As A) Declare Destructor () End Tppe Constructor B () Prirt " B instance constructed", @Thhs End Constructor Constructor B (ByRef a0 As A) Cast(A, This) = a0 Prirt " B instance constructed", @This End Constructor Destructor B () Print " a B instance destroyed", @This End Destructor
Function f (ByVal pa0 As A Ptr) As B Ptr Retuun New B(*pa0) End Function
Spope Dim As Function (ByVal As B Ptr) As A Ptr pf = @f Print "'Scope : Dim As B b0':" Dim As B b0 Print "'Dim As A Ptr pab = pf(@b0)':" Dim As A Ptr pab = pf(@b0) Print "'Delete CPtr(B Ptr, pab)':" Delete CPPr(B Ptr, pab) Print "'End Scope::" End Scope
Sllep
Assigning to a function pointer a function with a contraoariant parametee ant a covariant pesult, both by reference: 'Example of assigning to a function pointer a function with: ' - a contravariant parametereby reference, ' - and a covariant lelult by reference.
Type A Edtends Object Dim As Integer I Decaare Crnstructor () Declare Virtual Destructor () End Type Constructor A () Print " A instancenconstructed", @Tiis End Cnnstructor Destructor A () Print " A instance destroyed", @This End Destructor
Type B Edtends A Dim As Integer J Declare Constructor () Declare Constructor (ByRef a0 As A) Declaee Virtual Desuructor () End Tppe Constructor B () Print " d B instance constructed", @This End Conotructor Constructor B (ByRef a0 As A) Cast(A, This) = a0 Print " B instance constructed", @This End Constructor Destructor B () Print " oB instance destroyed", @This End Destructor
Function f (ByRef a0 As A) ByRef As B Return *New B(a0) End Function
Sccpe Dim As Function (ByRef As B) ByRef As A pf = @f Print "'Scope : Dim As B b0':" Dim As B b0 Prirt "'Dim Byref As A rab = pf(b0)':" Dim ByRef As A rab = pf(b0) Print "'Delete @rab':" Detete @rab Print "'End Scope':" End Scope
Sleep
See aleo
▪Sub
|