Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET
  • Page:
  • 1

TOPIC:

Passing objects by reference 09 Dec 2021 19:23 #20737

  • OhioJoe
  • OhioJoe's Avatar
  • Topic Author


  • Posts: 117
  • Another of my dumb questions:
    I've always been under the impression that objects are passed by reference. Apparently not so.
    CLASS JoeClass INHERIT Something
    HIDDEN JoeFile as XUseFile  // inherits from DBServer
    
    METHOD JoeMethod CLASS JoeClass
      SELF:JoeFile := XUseFile( "JOE.DBF" .. )
      WHILE !SELF:JoeFile:Eof
      	? XGetTheName( SELF:JoeFile )
      	SELF:JoeFile:Skip(1)
      ENDDO
      RETURN NIL
      
    FUNCTION XGetTheName( SomeFile AS XUseFile ) AS STRING STRICT
    	RETURN SomeFile:FIELDGET(#NAME)

    Apparently in the example above, the SELF:JoeFile object is copied when passed to XGetTheName() rather than passed by reference as I always assumed was the case. Variants of this occur hundreds of times in our main application so I'm thinking there might be a performance advantage to making the appropriate changes. First a couple of questions:

    1. Is it in fact true: the object above is NOT passed by reference ?
    2. And if so, how can I change the syntax so that it works in both VO and X# ?

    Thanks in advance for your assistance.
    Joe Curran
    Ohio USA

    Please Log in or Create an account to join the conversation.

    Passing objects by reference 09 Dec 2021 21:28 #20738

    • ic2
    • ic2's Avatar


  • Posts: 1574
  • Hello Joe,

    What happens here is that you open another instantiation of that dbServer. If you debug your application in VO and have a breakpoint somewhere, then click on the envelope in the upper left corner and select dbWork areas, you will see something like this
    No ALIAS
    1023 JOE.DBF
    1024 JOE_1.DBF

    and more like that with more instantiations.

    It also means that you should close your object on finalizing/closing the window or method where you assigned each DBServer object.

    Opening a DBF will come with a speed penalty. However, if you would open your DBF once, using something like a GLOBAL JoeFile object (or comparable), you must realize that doing something in 1 method, like a skip, moves the recordpointer in the global object with possible unwanted effects on the other places where you use JoeFile where you probably do not expect changes caused by other pieces of code.

    So you may not need/want to change it everywhere but some rather "static" databases could be opened once & centrally, like lookup tables with data like countries, languages etc.

    It would/could work the same in VO & X# for what you write as example.

    Dick

    Please Log in or Create an account to join the conversation.

    Passing objects by reference 09 Dec 2021 21:39 #20739

    • robert
    • robert's Avatar


  • Posts: 3293
  • Joe,

    In the code
    ? XGetTheName( SELF:JoeFile )

    You are passing the HIDDEN field JoeFile to the function.
    The parameter is declared as
    AS JoeFile

    That means that the original value inside SELF:JoeFile is NOT changed when you create a new object of type inside XGetTheName.

    However, since the XUseFile is a class, this is a Reference type. That means that SELF:JoeFile contains a reference to the object that is in the Heap of your program.
    In the call to XGetTheName you are creating a copy of the reference. That points to the same memory location, like in the image below:


    The same happens in VO and in X#. You are copying the reference, but both copies point to the same object in memory.

    Robert
    XSharp Development Team
    The Netherlands
    Attachments:

    Please Log in or Create an account to join the conversation.

    Passing objects by reference 09 Dec 2021 22:03 #20740

    • Chris
    • Chris's Avatar


  • Posts: 3759
  • I think there's a bit of confusion between "passed parameter by reference" and "passing a reference of the object", which are different things.
    When you use this:
    oMyObject := MyObject{}
    SomeFunc(oMyObject)
    ? oParam:Something // prints 1
    
    FUNCTION SomeFunc(oParam AS MyObject) AS VOID
    oParam:Something := 1
    
    CLASS MyObject
    EXPORT Something := 0 AS INT

    then a reference to the object is passed to the function (you "pass a reference to the object"), and when you change something to this object properties, it is reflected to the original variable passed to it.

    But when you do this:
    oMyObject := MyObject{}
    oParam:Something := 123
    SomeFunc(REF oMyObject) // or "@oMyObject"
    ? oParam:Something // prints 0 this time, as it's a new object
    
    FUNCTION SomeFunc(oParam REF MyObject) AS VOID
    oParam := MyObject{} // create and pass back a completely new object

    now you are "passing the parameter by reference". When you do that, then you can completely change the param and assign to it a completely new object, and this new object will be passed back to the code that calls the function.

    .
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.
    • Page:
    • 1