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 a raw pointer, which is not going to destroy on its own when leaving the areaCreateInstance creates an object in an "unstable" state with a refcount with zero, its self-negation when managing a link starts after something increments the AT LEAST ONCE counter, and then decreases it to zero; CComQIPtr above - an example of this
MSDN on CreateInstance :
The returned object has a reference count of zero, so call AddRef immediately, then use Release to release the reference to the object pointer when you are done.
What do you use instead of CComObject::CreateInstance ?
I have a helper template class CObjectPtr that acts just like the well-known CComPtr and wraps / manipulates the native C ++ class.
My code is:
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
This answer also contains another simple wrapper: What is the best way to initialize a reference counter for a non-created COM object? .
source share