This doesn't work:
clsTestDefaultInstance
Dim HowAmIInitialised As Integer
Private Sub Class_Initialize()
HowAmIInitialised = 99
End Sub
Public Sub CallMe()
Debug.Print "HowAmIInitialised=" & HowAmIInitialised
End Sub
i.e clsTestDefaultInstance.CallMe()
outputs HowAmIInitialised=99
because Class_Initialize()
is called even for the default instance.
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "clsTestDefaultInstance"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Compare Database
Option Explicit
' test how class instance can tell if it is default
'clsTestDefaultInstance
Dim HowAmIInitialised As Integer
Private Sub Class_Initialize()
HowAmIInitialised = HowAmIInitialised + 1
End Sub
Public Sub CallMe()
Debug.Print "HowAmIInitialised=" & HowAmIInitialised
End Sub
This is really, really simple... just compare the object pointer of the instance to the object pointer of the default instance:
'TestClass.cls (VB_PredeclaredId = True)
Option Explicit
Public Property Get IsDefaultInstance() As Boolean
IsDefaultInstance = ObjPtr(TestClass) = ObjPtr(Me)
End Property
Testing code shows that it works just fine:
Private Sub TestDefaultInstance()
Dim foo(9) As TestClass
Dim idx As Long
For idx = LBound(foo) To UBound(foo)
If idx = 5 Then
Set foo(idx) = TestClass
Else
Set foo(idx) = New TestClass
End If
Next
For idx = LBound(foo) To UBound(foo)
Debug.Print idx & foo(idx).IsDefaultInstance
Next
End Sub
With that said, note that this comes with a couple caveats:
The default instance can change if you Unload
it (for UserForm
's) or set it to Nothing
and then cause it to auto-instantiate again. It's best to think of VB_PredeclaredId
as kind of like a contract that you will always get an instance back if you use the class name directly. That contract does not guarantee that it will always be the same one. Adding the following code to the bottom of the TestDefaultInstance
procedure above will demonstrate:
'This doesn't effect anything that stored a reference to it.
Set TestClass = Nothing
'Make a call on the default to force it to reinstantiate.
Debug.Print TestClass.IsDefaultInstance
'This will now be false.
Debug.Print foo(5).IsDefaultInstance
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With