Pointers to Procedures
 
指向程序的指针

正如可以指向IntegerSingle类型的指针一样,指针也可以指向过程,也就是可以存储过程的地址。

宣言

要声明一个指向过程的指针,请使用SubFunction关键字,后跟任何参数和返回值类型:

' 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


参考