2012-04-21 38 views
11

Tôi đang đấu tranh để hiểu được thông qua giá trị và vượt qua bằng cách tham chiếu trong VB6. Tôi hiểu những khái niệm này hoàn toàn trong các ngôn ngữ lập trình hướng đối tượng như .NET và Java (tôi nhận ra rằng Java không có tham chiếu). Hãy xem mã bên dưới:VB6 vượt qua theo giá trị và vượt qua tham chiếu

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 

Hộp thư sẽ in 1 như tôi mong đợi. Nếu tôi đặt dấu ngoặc quanh Kiểm tra trên dòng 5, thì hộp thông báo sẽ in 1 như tôi mong đợi. Bây giờ, hãy xem mã bên dưới:

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 

Hộp thông báo in 2 như tôi mong đợi. Tuy nhiên, nếu bạn thêm dấu ngoặc vuông vào dòng 5 thì hộp thư sẽ in 1 như tôi không mong đợi. Có vẻ như hàm gọi có thể truyền theo giá trị ngay cả khi biến được định nghĩa trong hàm được gọi là ByRef. Dường như không phải là trường hợp ngược lại tức là nếu hàm được gọi có chữ ký với một biến được định nghĩa là ByVal thì nó sẽ luôn là ByVal (ngay cả khi không có dấu ngoặc xung quanh biến trong hàm gọi). Suy nghĩ đằng sau điều này trong VB6 là gì? Tôi nhận ra rằng đây là một câu hỏi cơ bản trong VB6 nhưng nó đã làm tôi bối rối. Tôi đã đọc tài liệu MSDN và tôi nhận ra rằng điều này là đúng, tuy nhiên nó không giải thích được suy nghĩ đằng sau nó.

Trả lời

16

Đây là hình ảnh cổ điển trong VB6. Đó là explained in the VB6 manual. Trong mã này dưới đây, VB6 xử lý các tranh luận như một biểu (Test) chứ không phải là một tài liệu tham khảo biến

TestFunction (Test) 

Để vượt qua một tham chiếu đến biến hoặc bỏ qua các dấu ngoặc hoặc sử dụng di sản Call statement (mà đòi hỏi dấu ngoặc đơn)

TestFunction Test 
Call TestFunction(Test) 

VB6 cho phép bạn chuyển biểu thức đến ByRef đối số ngay cả khi phương pháp thay đổi chúng. Ví dụ: bạn có thể viết

TestFunction (Test + 2) 

Trình biên dịch tạo bản sao tạm thời và chuyển qua tham chiếu. VB.Net uses brackets in a similar way.

Bạn cũng có thể nhận được biên dịch để tạo ra các bản sao tạm thời nếu TestFunction nhận hai đối số như thế này:

TestFunction (one), (two) 

Và bạn có thể nhận được bản sao tạm thời ngay cả với Call nếu bạn tăng gấp đôi dấu ngoặc của bạn, thêm một cặp hưởng ứng nhiệt liệt thêm:

Call TestFunction((Test)) 
+0

Cảm ơn. Điều này rất hữu ích. Mục đích của chức năng Gọi là gì? Điều này có nghĩa là biến được truyền sẽ không bao giờ được coi là biểu thức? Tôi ngạc nhiên bởi điều này như tôi chưa bao giờ thực sự nghĩ về nó trước đây. Ngoài ra, nếu có nhiều hơn một biến để vượt qua, sau đó tôi giả định rằng bạn không thể bao gồm một biểu thức? – w0051977

+2

Tôi không chắc chắn làm thế nào đây là một "gotcha" kể từ khi nó được tài liệu, hành vi có chủ ý. Từ khóa Cuộc gọi là kế thừa và không được dùng nữa, quay lại đầu MS Khái niệm cơ bản. Nó đã có để dễ dàng chuyển tiếp các chương trình cũ về phía trước. – Bob77

+2

Từ khóa 'Call' không có giá trị cho dù đối số có được coi là biểu thức hay không. Nó chỉ đơn giản là sử dụng dấu ngoặc đơn như là cách để vượt qua các đối số và do đó, một cặp dấu ngoặc đơn có ý nghĩa khác. Nhưng dấu ngoặc đơn xung quanh một đối số tạo ra một biểu thức giống như không có từ khóa 'Call'. –

6

Kèm theo bất kỳ biểu hiện trong ngoặc gây rằng biểu thức để được đánh giá đầu tiên trước khi làm bất cứ điều gì khác, ngay cả khi biểu hiện mà chỉ là một biến duy nhất. Trong trường hợp của bạn, kết quả của biểu thức đó sau đó được chuyển thành một đối số.

Vì vậy, bạn đang thực tế chuyển đối số theo tham chiếu. Nhưng đối số bạn đang truyền là kết quả của biểu thức chứ không phải biến ban đầu. Đây là lý do tại sao biến ban đầu không được cập nhật.

Các vấn đề liên quan