Add(New Class) : Is this kosher?

I want an array of some class. This question deals with how New instances of the class are created to fill the array.

I am using Point which is a built-in class of Xojo. It has an X and a Y property.

I previously have done something like this:

Var frogPoint() As Point
For i As Integer = 0 To 4
  Var tempFrog As New Point
  frogPoint.Add(tempFrog)
  frogPoint(i).X = i
  frogPoint(i).Y = i * 2
Next

This uses a Point variable (tempFrog) which when you leave the For/Next goes out of scope and disappears.

Var frogPoint() As Point
For i As Integer = 0 To 4
  frogPoint.Add(New Point)
  frogPoint(i).X = i
  frogPoint(i).Y = i * 2
Next

I tried this construction which seems to get rid of the need for the variable tempFrog all together. I cannot find this specifically discussed in the documentation. In my limited testing, it seems to work without Xojo objecting.

My question is is this a legitimate (reasonable) thing to do? Or is it something that will cause problems down the road?

It’s perfectly fine.

A more succinct version is this:

Var frogPoint() As Point
For i As Integer = 0 To 4
  frogPoint.Add(New Point(i, i * 2))
Next i
2 Likes

The two approaches are completely identical.

1 Like

I’ll just make a note here about an interesting result I got, that differs from what I expected:

The results:

       created point 1
       created point 2
       created point 3
       created point 4
       created point 5
       killing point 1
       killing point 2
       killing point 3
       killing point 4
       killing point 5

What I expected (unwinding from last to first):

       created point 1
       created point 2
       created point 3
       created point 4
       created point 5
       killing point 5
       killing point 4
       killing point 3
       killing point 2
       killing point 1

Private Sub Delayed_Quit()
  Quit
End Sub

Public Class DummyPoint

  Private Shared Property id_counter_ As Integer
  
  Public Sub Constructor(x As Integer, y As Integer)
    id = id_counter_ + 1
    id_counter_ = id
    System.DebugLog "created point "+id.ToString
  End Sub
  
  Public Sub Destructor()
    System.DebugLog "killing point "+id.ToString
  End Sub
  
  Public Property id As Integer

End Class


Sub Opening() Handles Opening

  Var points() As DummyPoint
  
  For i As Integer = 1 to 5
    Points.Add new DummyPoint(i, i)
  Next
  
  timer.CallLater(1, AddressOf Delayed_Quit)
  
End Sub

I would expect the first result, not the second.

If you create a linked list you should expect the elimination of the top links first undoing what was done in sequence until reaching the root ending the unwinding. Not breaking the chain from the start, orphaning the root right away, eliminating things that can have dependencies on previous states, thus, out of order, things needing undoing other things at the destroying time, could generate an unstable condition. So, last things done being released first going towards its root should be the less prompt to errors order.

At what point are you creating a linked list? It looks to me like you’re creating an array of unrelated objects. Maybe I’m misunderstanding.

Its a bunch of points, not a linked list.
What we are seeing is the memory being freed up.
There is no co-dependency between the items in the array
 apart from being ‘in an array’ - they could just as easily be (n) independant variables.

If the destruction order is important (cant see why it needs to be), then the array could be a class member, and the class could have a cleanup method to set the array members to nil in the any order you like

Yes. You both are taking the considerations about the nature of releasing a pile of objects too literally to what you guys see, not what’s behind the scenes. If the objects are “Points” or “parts of car” or whatever is not the question. If the stacking of objects was done adding them to an array or pushing to an user linked list, also does not matter. The point is, unwinding occurs backwards because the nature of undoing things, releasing other related resources in proper order for example, etc. Take for example the classic stack frame unwind, like what occurs with the stack frames when an exception happens, all finalizers all called from last to first, in the pile order, freeing resources in the proper order, releasing frames backwards, the inverse of the call order (the inverse of creation) until reaching the “root” where it is “catched” (unwind ends, goto somewhere). Just it. It’s classic. It’s not about myself, as always. Not about what I design. It’s about how the Xojo RT is designed, how it behaves.