Here is the code with inline comments:
{
CComObject<CMyAtlObject>* myAtlCOMObject = NULL;
HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject);
ASSERT(SUCCEEDED(hr));
// NOTE: Created new object with reference count of ZERO
{
const CComQIPtr<IMyAtlObject> pMyAtlObject = myAtlCOMObject;
// NOTE: Reference count increased to ONE
}
// NOTE: ~CComQIPtr went out of scope and called IUnknown::Release
// decrementing counter to ZERO; decrement to zero causes destruction
}
// NOTE: There is no ~CComObject call here on myAtlCOMObject going out of scope
// since myAtlCOMObject is a raw pointer
What am I missing?
You are missing the following:
CreateInstance
creates a new object and gets you raw pointer which is not going to self-destroy on leaving scope
CreateInstance
creates an object in "unstable" state with refcount of zero, it's self-desrtuction on reference management starts after something increments refcount AT LEAST ONCE and then decrements it to zero; CComQIPtr
above is an example of this
MSDN on CreateInstance
:
The object returned has a reference count of zero, so call AddRef immediately, then use Release to free the reference on the object pointer when you're done.
What do you use instead of CComObject::CreateInstance
?
I have a helper template class CObjectPtr
which acts in the way similar to well known CComPtr
and wraps/manages native C++ class.
My code would be:
CObjectPtr<CFoo> pFoo;
pFoo.Construct(); // Instantiates automatically adding reference
CFoo* pRawFoo = pFoo; // Acts as a pointer
CComPtr<IFoo> pFooInterface = pFoo; // Good for exposing inmepleted interafaces
CObjectPtr<CFoo> pAnotherFoo = pFoo; // Same instance proper reference counting
// ~CObjectPtr releases reference, destroys the object on last release
Another simple wrapper is also provided in this answer: How to better initialize a reference counter for a non-creatable COM object?.