Quick question about ByVal and ByRef when passing objects

  • Thread starter Thread starter Dmitry
  • Start date Start date
D

Dmitry

Hi there,

Just came across this problem and was wondering if someone
can shed a light on it as it somewhat puzzles me.
Suppose I have the following classes:

Public Class CTest
Private m_objCMember As CMember
Public Function addMember(ByVal objMember As CMember)
m_objCMember = objMember
End Function
End Class

Public Class CMember
Public strFirstName As String
Public strLastName As String
End Class

And the following code that uses them:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim objTest As New CTest
Dim objMember As New CMember

objMember.strLastName = "last name"
objMember.strFirstName = "First name"

objTest.addMember(objMember)

objMember.strFirstName = "TEST FIST NAME"
End Sub

How come when I run the last line of code (objMember.strFirstName = "TEST
FIST NAME")
- the value in the property objTest.m_objCMember.strLastName changes to
"TEST FIST NAME" as well.
I thought in VB when you pass parameters by value, it just passes a copy of
the object or variable
but not the reference!
Am I missing something here?
Thanks a million in advance
Cheers,
Dmitry
 
Am I missing something here?
i could be wrong but i think so

I thought in VB when you pass parameters by value, it just passes a copy of
the object or variable
but not the reference! Correct
but
Dim objTest As New CTest
Dim objMember As New CMember
You create your objects
objMember.strLastName = "last name"
objMember.strFirstName = "First name"
assign values to objMember
objTest.addMember(objMember)
add a reference to this instance of objMember to the objtest (objmember
can't be cloned) so it dousnt matter much that it is byval it still is the 1
instance (hope im not to much wrong here)
objMember.strFirstName = "TEST FIST NAME"
change the instance (they are sill regarded as the same object so it changes
on both locations)

unless you implement a clone function that returns a new instance of the
same class you will have this.

If i'm wrong correct me, i always want to learn :)

hope it helps

eric
 
Dmitry said:
How come when I run the last line of code (objMember.strFirstName =
"TEST FIST NAME")
- the value in the property objTest.m_objCMember.strLastName changes
to "TEST FIST NAME" as well.
I thought in VB when you pass parameters by value, it just passes a
copy of the object or variable
but not the reference!

Your class is a reference type. ByVal does pass a copy, but a copy of the
reference, not a copy of the object.

see also:
http://groups.google.com/[email protected]


--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
It only passes the value on items that are created on the Stack. the only
things that are created on the stack from what I've read are valuetype
variables (decimal,integer, etc) and structures. Classes are all created on
the managed heap, which by design uses reference types.
 
Dmitry said:
Hi there,

Just came across this problem and was wondering if someone
can shed a light on it as it somewhat puzzles me.
Suppose I have the following classes:

Public Class CTest
Private m_objCMember As CMember
Public Function addMember(ByVal objMember As CMember)
m_objCMember = objMember
End Function
End Class

Public Class CMember
Public strFirstName As String
Public strLastName As String
End Class

And the following code that uses them:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim objTest As New CTest
Dim objMember As New CMember

objMember.strLastName = "last name"
objMember.strFirstName = "First name"

objTest.addMember(objMember)

objMember.strFirstName = "TEST FIST NAME"
End Sub

How come when I run the last line of code (objMember.strFirstName = "TEST
FIST NAME")
- the value in the property objTest.m_objCMember.strLastName changes to
"TEST FIST NAME" as well.
I thought in VB when you pass parameters by value, it just passes a copy of
the object or variable
but not the reference!
Am I missing something here?
Thanks a million in advance
Cheers,
Dmitry
The object variables are references to the actual object. Therefore, when
you pass an object variable ByVal, you are actually passing the address of
the actual object.
 
Got it.
Why then when I call the following:

objMember = nothing

objMember gets "erased", while the objTest.m_objCMember
remains in the memory. Both of them point to the same address in the memory.
If I understand correctly when you assign Nothing to an object,
the memory block where it "sits" is released.
Thanks guys for your replies. Unfortunately unlike in C/C++ ,
memory management in VB and VB.Net is not very well
described in the books, which as in the example below can create a lot of
problems,
especially when you have to deal with a lot of classes/interfaces.
Cheers,
Dmitry
 
Thanks Peter,
Would you be able to point me to the resource on the web
or may be recommend a book where memory management in VB is described
please?
Thanks a million
D
 
When you set objMember to nothing, the objMember REFERENCE to the object is
deleted, not the object itself because it still referenced by the private
objTest.m_objCMember member.

Only when you set both objMember AND objTest.m_objCMember to Nothing, the
object, which is referenced by both variables, will be eligible for GC

Evert
 
Thank you
D

Evert Timmer said:
When you set objMember to nothing, the objMember REFERENCE to the object is
deleted, not the object itself because it still referenced by the private
objTest.m_objCMember member.

Only when you set both objMember AND objTest.m_objCMember to Nothing, the
object, which is referenced by both variables, will be eligible for GC

Evert


changes
 
Dmitry said:
Got it.
Why then when I call the following:

objMember = nothing

This is just removing a reference to the memory address. Once 0 references
exist GC can clean it up and give the memroy back the the system.
objMember gets "erased", while the objTest.m_objCMember
remains in the memory. Both of them point to the same address in the
memory.

Exactly... they both POINT.. remember pointers? kinda the same thing but
without all the *'s =)
If I understand correctly when you assign Nothing to an object,
the memory block where it "sits" is released.
Thanks guys for your replies. Unfortunately unlike in C/C++ ,
memory management in VB and VB.Net is not very well
described in the books, which as in the example below can create a lot of
problems,
especially when you have to deal with a lot of classes/interfaces.

That was kinda the goal, that we didn't have to worry about B.S. like this
anymore...
=)...

Oh well, there is always .NET 2.0 =)


-CJ
 
I know that. but it is good to know
how VB actually allocates memory, which is not
very well described.
Thanks for your help and have a good the rest of the day.
cheers
Dmitry
 
Back
Top