B4J Question Very interesting question about Classes.

LWGShane

Well-Known Member
Licensed User
Longtime User
So let's say I have two classes named "A" and "B". In each class's Initialize Sub, I initialize the other class. However, this causes a stack overflow error. Is there anyway that I can initialize "B" in "A" and "A" in "B" without causing a stack overflow error?

Thanks!
 

Roycefer

Well-Known Member
Licensed User
Longtime User
Your question isn't entirely clear. Are you creating a new A inside every B and a new B inside every A? If so, then no, you will always get a stack overflow because you have initiated the creation and initialization of an infinite number of objects.

If, however, the A that is inside B.Initialize() is merely a reference to an already-existing A (as opposed to a newly created one inside B.Initialize()) then you merely need to create a "base case" that escapes the recursion. You can check to see if A.IsInitialized and only call A.Initialize() if it's not. Do the same with the B that is inside A.
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
This creates an infinite loop of classes creation. A initializes B, which also initializes A then B again and so on...

The problem with recursion is how to stop the recursion to go to infinite. The only way you could do it, is by limiting the number of recursions.

For example:
B4X:
'This is ClassA
Sub Initialize(Depth as Int)
    If Depth < 10 then
        Depth = Depth + 1
        'Only initialize B if depth is less than 10
        Dim b As ClassB
        b.Initialize(Depth)
   End If
End Sub

And ClassB would have a similar code, checking the depth too.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I think this is a bug.

If you try:
B4X:
' ClassA
Sub Initialize
    Private b As ClassB
    b.Initialize
End Sub


' ClassB
Sub Initialize
  Private a As ClassA
  a.Initialize
End Sub

The code above should work without causing a stack overflow error
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Besides the fact that the code of my previous post should work but no :eek:...

So let's say I have two classes named "A" and "B". In each class's Initialize Sub, I initialize the other class. However, this causes a stack overflow error. Is there anyway that I can initialize "B" in "A" and "A" in "B" without causing a stack overflow error?
Why object B should initialize object A since it is already initialized? (If you want initialize B passing A to it, A must be already initialized).

If you want a relationship between two objects, you can use:
B4X:
' ClassA
Sub Class_Globals
   Private mObjB As ClassB
End Sub

'Initializes the object. You can add parameters to this method if needed.
Sub Initialize
End Sub

Sub setObjB(objB As ClassB)
   mObjB = objB
End Sub
Sub getObjB As ClassB
   Return mObjB
End Sub

Sub WhoIam
   Log("obj of type classA")
End Sub


B4X:
'ClassB
Sub Class_Globals
   Private mObjA As ClassA
End Sub

'Initializes the object. You can add parameters to this method if needed.
Sub Initialize(objA As ClassA)
  mObjA = objA
  objA.ObjB = Me
End Sub

Sub setObjA(ObjA As ClassA)
   mObjA = ObjA
End Sub
Sub getObjA As ClassA
   Return mObjA
End Sub

Sub WhoIam
   Log("obj of type classB")
End Sub


B4X:
'Main
Dim objA As ClassA
objA.Initialize

Dim objB As ClassB
objB.Initialize(objA)

objA.WhoIam
objA.ObjB.WhoIam

objB.WhoIam
objA.ObjB.WhoIam
 
Upvote 0
Top