VB6 按值传递和按引用传递

问题描述 投票:0回答:2

我正在努力理解 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 文档,我意识到这都是真的,但它没有解释其背后的原因。

vba vbscript vb6
2个回答
22
投票

这是 VB6 中的一个经典陷阱。 VB6 手册中对此进行了解释。在下面的代码中,VB6 将参数视为表达式(测试)而不是变量引用

TestFunction (Test)

为了传递对变量的引用,请省略括号或使用旧的

Call
语句(需要括号)

TestFunction Test
Call TestFunction(Test)

VB6 允许您将表达式传递给

ByRef
参数,即使方法更改了它们。例如你可以写

TestFunction (Test + 2)

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

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

TestFunction (one), (two)

如果你将括号加倍,添加一对额外的不必要的括号,即使使用

Call
你也可以获得临时副本:

Call TestFunction((Test))

7
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.