我正在努力理解按值传递并在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文档,我意识到这一切都是正确的,但它并没有解释它背后的原因。
答案 0 :(得分:18)
这是VB6中的经典问题。它是explained in the VB6 manual。在下面的代码中,VB6将参数视为表达式(Test)而不是变量引用
TestFunction (Test)
为了传递对变量的引用,省略括号或使用遗留Call
statement(需要括号)
TestFunction Test
Call TestFunction(Test)
VB6允许您将表达式传递给ByRef
参数,即使方法更改它们也是如此。你可以写
TestFunction (Test + 2)
编译器创建一个临时副本并通过引用传递它。 VB.Net uses brackets in a similar way。
如果TestFunction采用如下两个参数,你也可以让编译器创建临时副本:
TestFunction (one), (two)
如果您将括号加倍,即使使用Call
也可以获得临时副本,并添加额外的不必要的副本:
Call TestFunction((Test))
答案 1 :(得分:6)
将括号内的任何表达式括起来会导致在执行任何其他操作之前首先计算该表达式,即使该表达式只是单个变量。在您的情况下,该表达式的结果随后作为参数传递。
所以,你实际上是通过引用传递参数。但是你传递的参数是表达式的结果,而不是原始变量。这就是原始变量未更新的原因。