If I have an IUnknown *ptr, do I need to call Release() on every interface I obtain through ptr->QueryInterface(), in addition to calling ptr->Release() when I'm done with ptr?
I used to think that the answer is "Yes", but this quote from MSDN confused me:
Occasionally you may need to obtain a weak reference to an object (that is, you may wish to obtain a pointer to one of its interfaces without incrementing the reference count), but it is not acceptable to do this by calling
QueryInterfacefollowed byRelease.
I don't understand why that's problematic -- if I call ptr->QueryInterface() and then call Release on the resulting pointer, shouldn't the reference count on the object still be positive? How does that result in an invalid pointer?
The documentation is correct. And you need to follow reference counting rules - that includes calling
Releaseon interfaces obtained fromQueryInterfacein addition to after you created the object.To clear up why you can't do weak pointers with
Release- there exists a race condition in callingQueryInterfaceand thenReleaseimmediately after.QueryInterfacefor weak reference - reference count 2Releasefor weak reference - reference count 0. Object is destroyed.The warning is there to guard against the above - presumably some programmers think that they can "call
ptr->QueryInterface()and then callReleaseon the resulting pointer" and then use the object...