指向程序的指针
正如可以指向
Integer或
Single类型的指针一样,指针也可以指向过程,也就是可以存储过程的地址。
宣言
要声明一个指向过程的指针,请使用
Sub或
Function关键字,后跟任何参数和返回值类型:
' declares a pointer to sub procedure that takes no arguments
Dim pointerToProcedure As Sub
过程指针存储使用
操作符 @(地址)或
Procptr Operator检索的过程地址:
'' pfunc.bi
Function Add (a As Integer, b As Integer) As Integer
Return a + b
End Function
Dim pFunc As Function (As Integer, As Integer) As Integer = @Add
调用一个过程指针
程序指针的有趣之处在于可以像程序一样调用它们:
'' .. Add and pFunc as before ..
#include once "pfunc.bi"
Print "3 + 4 = " & pFunc(3, 4)
有关子程序指针的调用示例,请参阅
操作符 @ (Address Of)页面。
将过程指针传递给程序
将过程指针传递给其他过程也是类似的:
'' .. 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)
因为过程指针声明可能很长,它通常有助于为过程指针创建一个类型别名,以便使更清晰的代码:
'' .. Add and pFunc as before ..
#include once "pfunc.bi"
Type operation As Function (As Integer, As Integer) As Integer
Function DoOperation (a As Integer, b As Integer, op As operation) As Integer
Return op(a, b)
End Function
Print "3 + 4 = " & DoOperation(3, 4, @Add)
指向过程指针的指针
由于过程指针的语法不允许在过程是函数时声明指向过程指针的指针(因为ptr适用于返回类型,而不适用于过程),因此使用类型别名。请注意,调用该过程时,如何通过括号将取消引用的指针环绕到过程指针。这是因为函数调用运算符'()'的优先级高于
操作符 *(Value of):
Function Halve (ByVal i As Integer) As Integer
Return i / 2
End Function
Function Triple (ByVal i As Integer) As Integer
Return i * 3
End Function
Type operation As Function (ByVal As Integer) As Integer
' an array of procedure pointers, NULL indicates the
' end of the array
Dim operations(20) As operation = _
{ @Halve, @Triple, 0 }
Dim i As Integer = 280
' apply all of the operations to a variable by iterating through the array
' with a pointer to procedure pointer
Dim op As operation Ptr = @operations(0)
While (*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
指向成员程序
方法指针尚未实现,但是可以通过使用静态包装器来解决这个问题:
/''
' This example shows how you can simulate getting a class method pointer,
' until support is properly implemented in the compiler.
'
' When this is supported, you will only need to remove the static wrapper
' function presented here, to maintain compatibility.
'/
Type T
Declare Function test(ByVal number As Integer) As Integer
Declare Static Function test(ByRef This As T, ByVal number As Integer) As Integer
Dim As Integer i = 420
End Type
Function T.test(ByVal number As Integer) As Integer
Return i + number
End Function
Function T.test(ByRef This As T, ByVal number As Integer) As Integer
Return this.test(number)
End Function
Dim p As Function(ByRef As T, ByVal As Integer) As Integer
p = @T.test
Dim As T obj
Print p(obj, 69) '' prints 489
参考