Circular Relationships (VB6)
While I’m thinking about VB6 (not something I’ve done for a while) I remembered another common problem relating to the fact VB is a reference counted language rather than a garbage collected one.
The Problem
For an object to be destroyed it’s reference count must reach zero, this is fine in the majority of cases because VB will happliy clean up references that are no longer in scope. However when a circular reference is created (i.e Parent->Child and Child->Parent) the reference count will never reach 0.
The Common Solution
Ensure all references are released (set to nothing in VB parlance) in the Terminate event of the classes in question. This works fine as long as your development team are incredibly dilligent. Of course in practice what happens is you create memory leaks which take ages to track down.
A Beter Solution
Make the Child->Parent relationship weak (i.e doesn’t increment the reference count on Parent). This can be accomplished with the following code (in a class)
Private Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory” (dest As Any, source As Any, ByVal bytes As Long)
Dim m_lParentPtr as Long
Public Property Set Parent(oParent as CParent)
’ ObjPtr is an undocumented function
m_lParentPtr = ObjPtr(oParent)
End Property
Public Property Get Parent as CParent
Dim oParent As CParent
’ Generate an object from the pointer
CopyMemory oParent, m_lParentPtr, 4
’ Return it to the caller
Set Parent = oParent
’ Kill the illegal reference(Your other option is to Increment the reference count on the illegal object to make it legal)
CopyMemoryAny(WeakRef, 0&, 4&)
End Property
Private Sub IncrementRefCount
’ Increments reference counter (simulates IUnkown.AddRef)
Dim lngRc As Long
CopyMemory lngRc, ByVal (ObjPtr(Me)) + 4, 4 ‘ Get reference counter value…
CopyMemory ByVal (ObjPtr(Me)) + 4, (lngRc + 1), 4 ‘ …and increment it
End Sub
Public Function RefCount As Long
’ returns the reference counter of obj
Dim lngRc As Long
CopyMemory lngRc, ByVal (ObjPtr(Me)) + 4, 4 ‘ Get reference counter…
RefCount = lngRc - 2
End Function
PS: I haven’t checked this compiles because I don’t have a copy of VB6 handy but the important bits are correct…









There is another way to deal with the circular reference problem that often works: create a new class of objects to hold the information that is common to the parent and children. Give the parent and children a reference to this object. Doesn’t solve every problem but it is fully automatic. See http://en.wikibooks.org/wiki/Programming:Visual_Basic_Classic/Effective_Programming#Avoiding_and_Dealing_with_Circular_References