Re: owner of class
From: Mike D Sutton (EDais_at_mvps.org)
Date: 12/30/04
- Next message: Gary Paris: "Reading Contact information from Outlook in VB6"
- Previous message: Veign: "Re: VB executable hangs randomly"
- In reply to: Al Meadows: "owner of class"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 30 Dec 2004 19:43:19 -0000
> I have an application where I use a lot of class modules. At least a
> hundred, and some of these
>
> Something that I think would help me during debugging is to know what class
> objects are currently initialized, what intanciated them (i.e. myclass1
> created an instance of myclassX and myclass2 created an instance of myclassX.)
>
> One way I was thinking of doing it was to include a variable or two in each
> class module that gets set when the class is created that contains the
> specific name of the class (i.e. cAcct might be set goodAcct = new cAcct and
> set baddAcct = new cAcct). Then, add a set of AddToStack/RemoveFromStack
> functions to each class that would maintain an inventory of existing class
> objects.
>
> What I want to accomplish is to identify possible situations where I
> terminate a given object but because I've created circular reference, the
> class doesn't terminate until after I terminate one or more other classes.
>
> What I would like to be able to do is have a hidden interface 'feature' that
> would display a list of all of the active classes and who called them. Then,
> I could easily tell of a class was still active after I thought it should be
> closed.
>
> Example:
>
> Module/Class/Form Instance Name Class
> ===========================
> frmMain goodAcct cAcct
> frmMain badAcct cAcct
> frmMain strClass cString
> myClass strClass cString
>
> I don't suppose there is anyway to ask the application itself (i.e. is there
> some sort of reachable collection of active classes already) without needing
> me to create and manage my own?
One way of doing this is to have an Attach and Detach method of each class that allows it to store it's parent object, probably the
easiest way of doing this is you have multiple classes in your project is to use an interface which exposes the functionality:
'*** IParentTrack
Public Property Get ParentObj() As Object
End Property
Public Sub AttachParent(ByRef inParent As Object)
End Sub
Public Function DetachParent() As Boolean
End Function
'***
Then each class you need to know it's parent object can simply implement the interface:
'***
Implements IParentTrack
Dim m_ParentObj As Object
Private Property Get IParentTrack_ParentObj() As Object
Set IParentTrack_ParentObj = m_ParentObj
End Property
Private Sub IParentTrack_AttachParent(ByRef inParent As Object)
m_ParentObj = inParent
End Sub
Private Function IParentTrack_DetachParent() As Boolean
IParentTrack_DetachParent = Not (m_ParentObj Is Nothing)
m_ParentObj = Nothing
End Function
'***
You must remember to call DetachParent() on each before you want to destroy it though otherwise you're left with a circular
reference. If you don't like this solution then you could store a 'soft pointer' to the parent by using the ObjPtr() function
instead:
'*** IParentTrack
Public Property Get ParentPtr() As Long
End Property
Public Sub AttachParent(ByRef inParent As Object)
End Sub
Public Function DetachParent() As Boolean
End Function
'***
'***
Implements IParentTrack
Dim m_ParentPtr As Long
Private Property Get IParentTrack_ParentPtr() As Long
IParentTrack_ParentPtr = m_ParentPtr
End Property
Private Sub IParentTrack_AttachParent(ByRef inParent As Object)
m_ParentObj = ObjPtr(inParent)
End Sub
Private Function IParentTrack_DetachParent() As Boolean
IParentTrack_DetachParent = (m_ParentPtr <> 0)
m_ParentObj = 0
End Function
'***
This doesn't quite give you the flexibility of the first solution, but doesn't create any circular references. If you need to get
back to the parent object from the pointer then you can use this function:
'***
Private Declare Sub PutDWord Lib "MSVBVM60.dll" Alias _
"PutMem4" (ByRef inDst As Any, ByVal inSrc As Long)
...
Private Function ResolveObjPtr(ByVal inPtr As Long) As Object
Dim TempObj As Object
If (inPtr) Then
Call PutDWord(TempObj, inPtr)
Set ResolveObjPtr = TempObj
Call PutDWord(TempObj, 0&)
End If
End Function
'***
If the parent object has already been released though, this will give you back an invalid object which will more thank likely kill
the IDE if you attempt to use it, so be careful when using it..
If you're in a position to use a class factory for your object creating then it's possible to add parent/child relationships
directly into it including communication between the parent and child classes for when either gets destroyed - Have a look at the
class factory and subject/observer design patterns if you want to know more on this approach.
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: http://EDais.mvps.org/
- Next message: Gary Paris: "Reading Contact information from Outlook in VB6"
- Previous message: Veign: "Re: VB executable hangs randomly"
- In reply to: Al Meadows: "owner of class"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|