12

我正在努力理解 VB6 中的值传递和引用传递。我在 .NET 和 Java 等面向对象的编程语言中完全理解这些概念(我意识到 Java 没有通过引用传递)。看看下面的代码:

Private Sub Form_Load()

Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox (Test)

End Sub

Private Sub TestFunction(ByVal i As Integer)
    i = i + 1
End Sub

当我在第 5 行的 Test 周围加上括号时,消息框会按我的预期打印 1。现在看看下面的代码:

Private Sub Form_Load()

Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox Test

End Sub

Private Sub TestFunction(ByRef i As Integer)
    i = i + 1
End Sub

正如我所料,消息框打印 2 。但是,如果您在第 5 行添加方括号,那么消息框会打印 1,这与我的预期不同。即使被调用函数中定义的变量是 ByRef,调用函数似乎也可以按值传递。反之亦然,即如果被调用函数的签名带有定义为 ByVal 的变量,那么它将始终是 ByVal(即使调用函数中的变量周围没有括号)。VB6背后的想法是什么?我意识到这是 VB6 中的一个基本问题,但它让我感到困惑。我已经阅读了 MSDN 文档,我意识到这一切都是真的,但是它并没有解释其背后的原因。

4

2 回答 2

20

这是 VB6 中的经典问题。VB6 手册中对此进行了说明。在下面的代码中,VB6 将参数视为表达式(Test) 而不是变量引用

TestFunction (Test)

为了传递对变量的引用,要么省略括号,要么使用遗留Call语句(需要括号)

TestFunction Test
Call TestFunction(Test)

VB6 允许您将表达式传递给ByRef参数,即使方法更改了它们。例如你可以写

TestFunction (Test + 2)

编译器创建一个临时副本并通过引用传递它。VB.Net以类似的方式使用括号

如果 TestFunction 采用如下两个参数,您还可以让编译器创建临时副本:

TestFunction (one), (two)

即使将括号加倍,也可以获得临时副本Call,添加一个额外的不必要的对:

Call TestFunction((Test))
于 2012-04-21T19:27:30.070 回答
6

将任何表达式括在括号内会导致在执行任何其他操作之前先计算该表达式,即使该表达式只是一个变量。在您的情况下,该表达式的结果然后作为参数传递。

因此,您实际上是通过引用传递参数。但是您传递的参数是表达式的结果,而不是原始变量。这就是为什么原始变量没有得到更新的原因。

于 2012-04-21T19:32:21.860 回答