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 は引数を変数参照ではなく式(テスト) として扱います。

TestFunction (Test)

変数への参照を渡すには、括弧を省略するか、レガシーCallステートメントを使用します(括弧が必要です)。

TestFunction Test
Call TestFunction(Test)

VB6 ではByRef、メソッドによって変更された場合でも、式を引数に渡すことができます。例えば、あなたは書くことができます

TestFunction (Test + 2)

コンパイラは一時コピーを作成し、それを参照渡しします。VB.Netは同様にブラケットを使用します

TestFunction が次のように 2 つの引数を取る場合、コンパイラに一時コピーを作成させることもできます。

TestFunction (one), (two)

Callまた、ブラケットを 2 倍にして不要なペアを追加しても、一時的なコピーを取得できます。

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

式を括弧で囲むと、その式が単一の変数である場合でも、他の処理を行う前にその式が最初に評価されます。あなたの場合、その式の結果は引数として渡されます。

したがって、実際には、参照によって引数を渡していることになります。ただし、渡す引数は式の結果であり、元の変数ではありません。これが、元の変数が更新されない理由です。

于 2012-04-21T19:32:21.860 に答える