Reference counting in clients


Now let’s look at some client code. Assume the following real Visual Basic
fragment:

Dim toughluck As CHardway, toobad As CHardway, forgetit As CHardway
Set toughluck = New CHardway
Set toobad = toughluck
Set forgetit = toobad
Set toobad = Nothing
Set toughluck = forgetit

Notice that the last assignment is redundant because toughluck already has a CHardWay object, but we’re going to do it anyway to illustrate a point. Let’s work through the reference counting using the B-- dialect:

‘’ Dim toughluck As CHardway, toobad As CHardway, forgetit As CHardway
Dim toughluck As CLSID_CHardway = 0, toobad As CLSID_CHardway = 0
Dim forgetit As CLSID_CHardway = 0
’’ Set toughluck = New CHardway
toughluck = CreateInstance(CLSID_CHardway, IID_IHardway) ‘ c = 1
if toughluck = 0 Then Goto ErrorHandler
’’ Set toobad = toughluck
’ Includes automatic AddRef by QueryInterface
toobad = IUnknown(toughluck).QueryInterface(IID_IHardway) ‘ c = 2
if toobad = 0 Then Goto ErrorHandler
’’ Set forgetit = toobad
’ Includes automatic AddRef
forgetit = IUnknown(toobad).QueryInterface(IID_IHardway) ‘ c = 3
if forgetit = 0 Then Goto ErrorHandler
’’ Set toobad = Nothing
IUnknown(toobad).Release ‘ c = 2
toobad = 0
’’ Set toughluck = forgetit
IUnknown(toughluck).Release ‘ c = 1
’ Includes automatic AddRef
toughluck = IUnknown(forgetit).QueryInterface(IID_IHardway) ‘ c = 2
if toughluck = 0 Then Goto ErrorHandler

An assignment statement in Visual Basic translates into two statements in B--. The first B-- statement calls Release on the object variable being assigned to (the left side) to unreference whatever that variable referenced before. The second B-- statement calls QueryInterface on the object being assigned (the right side) and passes the type of the object being assigned to (the left side). If the types are compatible, the assignment succeeds and AddRef will be called on the assigned object variable to count the new reference.


Make sure you never call QueryInterface, Release, or AddRef on an object variable that is Nothing (0). Nothing has no methods, and calling them will get you in big trouble.


If you think this doesn’t look all that bad, well, you’re not seeing how many times I had to rewrite the code to get it past the human compilers, Glenn Hackney and Marc Young. Of course, we still don’t know whether this code would compile on a real B-- compiler.