Flylib.com

Books Software

 
 
 

Chapter 6 -- Object By Value

[Previous] [Next]

Chapter 6

Object By Value

A programmer new to object-oriented programming in Microsoft Visual Basic might assume that all that is required to pass an object by value is to include the ByVal reserved word in a function declaration. For example:

PublicSubFoo(ByValbrAsBar)
br.color=GREEN
EndSub

One could mistakenly infer that if the function caller passed in a Bar object that the Visual Basic compiler would create a copy of the object. The function code block could then manipulate the copy without affecting the original. For example:

DimmyBarAsBar

SetmyBar=NewBar
myBar.color=BLUE
CallFoo(myBar)

'Question:DoesmyBar.color=BLUE?
'
'Answer:No.ThevalueofmyBar.colorisGREEN.

The value of myBar.color changes in the calling program because passing an object by value actually passes a reference to the object. For an explanation of this functionality, refer back to Chapter 2.

Another common misconception along the same lines is that if a class defines only a Property Get procedure to return an object and not a Property Set procedure, the class property is read-only. For example:

'ClassModuleFoo
'
Privatem_BarAsBar

PublicPropertyGetTheBar()AsBar
SetTheBar=m_Bar
EndProperty

One might then assume that the Visual Basic compiler will return a copy of the Bar object when the TheBar Property Get procedure is called, and whatever the caller does to it has no effect on the original. For example:

DimmyFooAsFoo
DimmyColorAsColor

SetmyFoo=NewFoo

'Youcandothis.
myColor=myFoo.TheBar.Color

'Question:Canyoudothis?
myFoo.TheBar.Color=PURPLE

'Answer:Yes,becauseacopyoftheobjectreferencetoaBar
'objectisreturnedtotheTheBarPropertyGetprocedure,
'notacopyoftheobjectitself.

In both of the previous source code examples, a copy of an object reference is returned—not a copy of an object. To review the explanation provided in Chapter 2, an object variable in Visual Basic contains a reference to an object, not the object itself. Therefore, when an object variable is passed by value, a copy of the object variable is created that references the same object. Hence actions performed on all copies of an object variable affect the same object.

The Object By Value design pattern described in this chapter enables you to pass an object by value—passing a copy of the object rather than the object reference—by writing the object's state to a data stream, passing the data stream to the recipient process that constructs a copy of the object, and updating the new object's state from the data stream. This will produce an exact copy of the original object in the recipient process's address space.

[Previous] [Next]

Purpose

The Object By Value design pattern passes or returns an object by value from one function process to another, resulting in the receiving process obtaining a copy of the object rather than a copy of an object reference.

[Previous] [Next]

Utilization

Use the Object By Value design pattern in the following circumstances:

  • To pass or return a copy of an object to a caller This will protect the original object from unwanted state changes. For example, you can modify the property values of an object that is passed or returned by value without impacting the original object.
  • To pass or return a copy of an object from one process to another This allows the recipient process to fully benefit from the services offered by an object without having to incur the performance cost usually associated with cross-process object interaction. When a COM object is created in the client process, the client directly references a memory address in its process space, resulting in immediate method invocation. COM objects created outside the client process suffer from significantly slower response times because a client process cannot reference the memory addresses of objects in other processes. Instead COM interposes and creates a proxy object in the client process that the client references directly in memory. When the client invokes a method on the object, a procedure known as marshaling occurs: The proxy object packages the request into a well-defined data packet and forwards the request to a stub object that unpackages the request and invokes the method on the real object. The reverse occurs if the method has a return value or has parameters that are passed by reference. To avoid the major performance hit involved in marshaling data across process boundaries you can create a copy of the object in the client process. All object method invocations will then happen directly on the local copy of the object.
  • To pass or return a copy of an object between dissimilar object systems This task is difficult to accomplish without using the Object By Value design pattern. For example, you might want to create the original object in Visual Basic and then pass a copy of it to a Java application. Java and Visual Basic have different semantics and syntax for defining an object, but, providing both sides agree on how to interpret a data stream, it's possible to "re-hydrate" an object created in one language platform in another.