For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic > February 2006 > ByRef or ByVal









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author ByRef or ByVal
Ven

2006-02-22, 6:55 pm

Is a new object created within the Function when a object is passed by Value
? If so would it make sense to pass the argument ByRef when we are not
modifying any properties of the object within the Function?

Thank You
Ralph

2006-02-22, 6:55 pm


"Ven" <Ven@discussions.microsoft.com> wrote in message
news:1F9F3293-08A8-4576-99F6-ACD96559C057@microsoft.com...
> Is a new object created within the Function when a object is passed by

Value
> ? If so would it make sense to pass the argument ByRef when we are not
> modifying any properties of the object within the Function?
>
> Thank You


When passing an "object" you are actually passing a 'Reference" (a handle or
pointer) no matter which keyword you use in this context. So no, you are not
creating a copy. Either will refer to a Reference for the object.

-ralph




Mike D Sutton

2006-02-22, 6:55 pm

> Is a new object created within the Function when a object is passed by
> Value
> ? If so would it make sense to pass the argument ByRef when we are not
> modifying any properties of the object within the Function?


The only difference when passing an object BrRef/ByVal if that ByRef will
allow you to change the original object reference however ByVal will not.
For example, setting the object to a new object in a routine which has been
passed the object ByVal will have no effect on the original object, passing
it ByRef will also reset the original handle.

'***
Private Sub Form_Load()
Dim A As New Collection
Call A.Add("A")

Call TestVal(A)
Debug.Print "After ByVal: " & CStr(A.Count)

Call TestRef(A)
Debug.Print "After ByRef: " & CStr(A.Count)
End Sub

Private Sub TestVal(ByVal inA As Collection)
Set inA = New Collection
End Sub

Private Sub TestRef(ByRef inA As Collection)
Set inA = New Collection
End Sub
'***

This creates a new collection object and adds a string to it. This objects
then passed to two routines which both simply assign the value to a new
collection object, the first is passed ByVal and has no effect on the
original object, while the second is ByRef and as such changes the original
object also (resets its count.)

***
After ByVal: 1
After ByRef: 0
***

Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Phill W.

2006-02-22, 6:55 pm


"Ven" <Ven@discussions.microsoft.com> wrote in message
news:1F9F3293-08A8-4576-99F6-ACD96559C057@microsoft.com...
> Is a new object created within the Function when a object is passed by
> Value
> ? If so would it make sense to pass the argument ByRef when we are not
> modifying any properties of the object within the Function?


When working with Objects and functions, you are passing a
reference (dare I say "Pointer"?) to the object, not a copy of
the object itself.
However you pass it, you will be able to modify the Object, as in

[SomeClass.cls]
Public Property Let Thing(ByVal i as Integer )

[OtherCode.bas]
Dim X As SomeClass
Set X = New SomeClass
.. . .
Call FixObject( X )
.. . .
Sub FixObject( ByVal X As SomeClass )
X.Thing = 77
End Sub

Only pass Objects ByRef if your method instends to create a
/new instance/ of the object and "return" it to the caller, as in

Dim X As SomeClass
Set X = New SomeClass
.. . .
Call RenewObject( X )
.. . .
Sub RenewObject( ByRef X As SomeClass )
Set X = New SomeClass
End Sub

HTH,
Phill W.


Tony Proctor

2006-02-22, 6:55 pm

....or, to paraphrase everyone else a little more compactly:-

"ByVal Object" passes an object pointer by-value, whilst "ByRef Object"
passes an object pointer by-reference.

The difference is just one level of indirection. Both mechanisms will allow
changes to the members of the object, but ByRef will additionally allow the
complete object to be replaced by another one.

Tony Proctor

"Ven" <Ven@discussions.microsoft.com> wrote in message
news:1F9F3293-08A8-4576-99F6-ACD96559C057@microsoft.com...
> Is a new object created within the Function when a object is passed by

Value
> ? If so would it make sense to pass the argument ByRef when we are not
> modifying any properties of the object within the Function?
>
> Thank You



Rob R. Ainscough

2006-02-22, 6:55 pm

And my 2 cents,

ByRef is actually faster also

"Ven" <Ven@discussions.microsoft.com> wrote in message
news:1F9F3293-08A8-4576-99F6-ACD96559C057@microsoft.com...
> Is a new object created within the Function when a object is passed by
> Value
> ? If so would it make sense to pass the argument ByRef when we are not
> modifying any properties of the object within the Function?
>
> Thank You



Mike D Sutton

2006-02-22, 6:55 pm

> And my 2 cents,
> ByRef is actually faster also


With all the advanced optimisation compilation settings checked, I find the performance to be pretty much identical
between the two..
FWIW,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Ralph

2006-02-23, 3:55 am


"Rob R. Ainscough" <robains@pacbell.net> wrote in message
news:%23r$rtd$NGHA.3196@TK2MSFTNGP09.phx.gbl...
> And my 2 cents,
>
> ByRef is actually faster also
>


A 'speed' difference between ByRef/ByVal is related to the OP's question
about whether a new object is created or not. In the case of passing a
String ByVal, then a 'copy' is created and there are extra clicks, compared
to passing it ByRef. Little difference is noted when passing objects.

-ralph




> "Ven" <Ven@discussions.microsoft.com> wrote in message
> news:1F9F3293-08A8-4576-99F6-ACD96559C057@microsoft.com...
>
>



Ven

2006-02-23, 6:55 pm

So to summarize...

For Objects:
Use ByRef if you want to modify the object's properties in the
function/sub-routine
Use ByVal if you want to just read the object's properties in the
function/sub-routine

For Intrinisc or Primitve Datatypes:
ByVal add's extra over head. So avoid passing ByVal unless you dont want to
pass it ByRef for some reason.

Is that true?


"Ralph" wrote:

>
> "Rob R. Ainscough" <robains@pacbell.net> wrote in message
> news:%23r$rtd$NGHA.3196@TK2MSFTNGP09.phx.gbl...
>
> A 'speed' difference between ByRef/ByVal is related to the OP's question
> about whether a new object is created or not. In the case of passing a
> String ByVal, then a 'copy' is created and there are extra clicks, compared
> to passing it ByRef. Little difference is noted when passing objects.
>
> -ralph
>
>
>
>
>
>
>

Bob Butler

2006-02-23, 6:55 pm

"Ven" <Ven@discussions.microsoft.com> wrote in message news:81F6AF13-
8454-4B7A-8473-E8B2AB534263@microsoft.com
> So to summarize...
>
> For Objects:
> Use ByRef if you want to modify the object's properties in the
> function/sub-routine
> Use ByVal if you want to just read the object's properties in the
> function/sub-routine


No. Use ByRef if you want to change what object the reference points to;
use ByVal if you want to make sure that the procedure does not change that.

You are *NOT* passing the object, you are passing a variable containing a
reference to the object. Understanding that distinction is absolutely
critical.

> For Intrinisc or Primitve Datatypes:
> ByVal add's extra over head. So avoid passing ByVal unless you dont
> want to pass it ByRef for some reason.


Passing a String ByVal means creating a copy and that adds overhead so you
may want to consider passing them ByRef if you are in a set of procedures
that run for a long time and make thousands of calls that pass string
parameters. For most data types and situations the "overhead" is negligible
at best.

IMO it's usually more important to use ByVal or ByRef to document whether or
not a procedure modifies the contents of the parameter. If it does then it
is ByRef, if not then it should be ByVal. That way when you glance at the
procedure declaration you know immediately what does and does not get
modified.

--
Reply to the group so all can participate
VB.Net: "Fool me once..."

Jeff Johnson [MVP: VB]

2006-02-23, 6:55 pm


"Ven" <Ven@discussions.microsoft.com> wrote in message
news:81F6AF13-8454-4B7A-8473-E8B2AB534263@microsoft.com...

> So to summarize...
>
> For Objects:
> Use ByRef if you want to modify the object's properties in the
> function/sub-routine
> Use ByVal if you want to just read the object's properties in the
> function/sub-routine


NO!

BOTH ByRef and ByVal will allow you to modify the object's properties.
Here's a better summary:

As far as objects are concerned, ByRef and ByVal are virtually identical.


Ven

2006-02-23, 6:55 pm

Here is a sample code. Not sure if for Objects ByRef and ByVal are same or am
I understanding you right


Private Sub Command1_Click()

Dim xmlDocMain As MSXML2.DOMDocument30
Set xmlDocMain = New MSXML2.DOMDocument30

'Load xml
xmlDocMain.loadXML ("<Test/>")

Call passByVal(xmlDocMain)
Debug.Print xmlDocMain.xml 'Prints XML <Test/>

'Pass By Reference
Call passByRef(xmlDocMain)
Debug.Print xmlDocMain.xml ' Error since passByRef set xmlDocMain Nothing

'Clean up
Set xmlDocMain = Nothing
End Sub

Sub passByRef(ByRef xmlDocRef As MSXML2.DOMDocument30) 'Is a new xmlDoc
object created ??
Set xmlDocRef = Nothing
End Sub

Sub passByVal(ByVal xmlDocVal As MSXML2.DOMDocument30) 'Is a new xmlDoc
object created ??
Set xmlDocVal = Nothing
End Sub




"Jeff Johnson [MVP: VB]" wrote:

>
> "Ven" <Ven@discussions.microsoft.com> wrote in message
> news:81F6AF13-8454-4B7A-8473-E8B2AB534263@microsoft.com...
>
>
> NO!
>
> BOTH ByRef and ByVal will allow you to modify the object's properties.
> Here's a better summary:
>
> As far as objects are concerned, ByRef and ByVal are virtually identical.
>
>
>

Ven

2006-02-23, 6:55 pm

Here is a better example, Intinsic and Objects.


Private Sub Command1_Click()

Dim xmlDocMain As MSXML2.DOMDocument30 'Object
Dim intTestMain As Integer 'Primitive Data Type

Set xmlDocMain = New MSXML2.DOMDocument30


'Load xml
xmlDocMain.loadXML ("<Test/>")
intTestMain = 1

Call passByVal(xmlDocMain, intTestMain)
Debug.Print xmlDocMain.xml 'Prints XML <Test/>
Debug.Print intTestMain 'Prints Hello World

'Pass By Reference
Call passByRef(xmlDocMain, intTestMain)
Debug.Print intTestMain 'Prints blank
Debug.Print xmlDocMain.xml ' Error since passByRef set xmlDocMain Nothing


'Clean up
Set xmlDocMain = Nothing
End Sub

Sub passByRef(ByRef xmlDocRef As MSXML2.DOMDocument30, ByRef intTestByRef As
Integer) 'Is a new xmlDoc object created ??
intTestByRef = 0
Set xmlDocRef = Nothing
End Sub

Sub passByVal(ByVal xmlDocVal As MSXML2.DOMDocument30, ByVal intTestByVal As
Integer) 'Is a new xmlDoc object created ??
intTestByVal = 0
Set xmlDocVal = Nothing
End Sub


"Jeff Johnson [MVP: VB]" wrote:

>
> "Ven" <Ven@discussions.microsoft.com> wrote in message
> news:81F6AF13-8454-4B7A-8473-E8B2AB534263@microsoft.com...
>
>
> NO!
>
> BOTH ByRef and ByVal will allow you to modify the object's properties.
> Here's a better summary:
>
> As far as objects are concerned, ByRef and ByVal are virtually identical.
>
>
>

Jeff Johnson [MVP: VB]

2006-02-23, 6:55 pm


"Ven" <Ven@discussions.microsoft.com> wrote in message
news:1EC27C83-BD93-43DF-ABAE-6BD99E7CCD76@microsoft.com...

> Sub passByRef(ByRef xmlDocRef As MSXML2.DOMDocument30) 'Is a new xmlDoc
> object created ??


In VB, when passing an object type to a procedure, a new object is never
ever EVER created, REGARDLESS of whether you use ByRef or ByVal. This is why
I said that for objects, ByRef and ByVal are VIRTUALLY identical. Yes, there
are some under-the-covers differences, but they have nothing to do with a
copy of the object being created, because that never happens.


Ven

2006-02-23, 6:55 pm

Thank you. That makes things clear.(Under the cover differences)

"Jeff Johnson [MVP: VB]" wrote:

>
> "Ven" <Ven@discussions.microsoft.com> wrote in message
> news:1EC27C83-BD93-43DF-ABAE-6BD99E7CCD76@microsoft.com...
>
>
> In VB, when passing an object type to a procedure, a new object is never
> ever EVER created, REGARDLESS of whether you use ByRef or ByVal. This is why
> I said that for objects, ByRef and ByVal are VIRTUALLY identical. Yes, there
> are some under-the-covers differences, but they have nothing to do with a
> copy of the object being created, because that never happens.
>
>
>

Bob O`Bob

2006-02-23, 9:55 pm

Ven wrote:
> Thank you. That makes things clear.(Under the cover differences)
>



It need not stay so obscure, if that's what you're questioning.

VB never "passes" objects, it passes a reference.
All byVal does is keep the recipient procedure from being able to
re-target that reference to point to some other object.

ByVal ... as object
"Here's [a temporary pointer to] an object - change the object all you like,
but if you change the pointer itself, after you return we won't even notice."

ByRef ... as object
"Here's [complete access to] our pointer to an object."




Bob
--
Karl E. Peterson

2006-02-23, 9:55 pm

Bob O`Bob wrote:
> ByVal ... as object
> "Here's [a temporary pointer to] an object - change the object all
> you like, but if you change the pointer itself, after you return we
> won't even notice."
>
> ByRef ... as object
> "Here's [complete access to] our pointer to an object."


That's as succinct as I've heard that put. Nice.
--
Working without a .NET?
http://classicvb.org/


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com