Your function's return type is a raw IDispatch* pointer, not an IComItemPtr object (or at least an IDispatchPtr object). The issue you are seeing is due to you incorrectly mixing a smart pointer with a raw pointer.
Since your function does not return a smart wrapper object, a conversion must be performed to convert pItem to IDispatch*. The only conversion that pItem can perform in this situation is to IComItem*, which the compiler can then implicitly convert to IDispatch* (since IComItem derives from IDispatch, otherwise your code wouldn't compile at all).
IOW, your return statement is effectively doing this logic:
LPDISPATCH func()
{
IComItemPtr pItem = m_pItem;
pItem = pItem->GetParent(); // Returns parent as IComItemPtr
//return pItem;
IComItem *pTemp = pItem.operator IComItem*();
IDispatch *pDisp = (IDispatch*) pTemp;
return pDisp;
} // <-- pItem is destructed here!
No matter what, pItem itself is always going to go out of scope when the function exits, decrementing the object's refcount if pItem is referencing an object.
So, what is important is that you return a IDispatch* pointer to a valid object that has its refcount incremented so the object is not freed when pItem's destructor decrements its refcount.
Try this instead:
IComItemPtr func()
{
return m_pItem->GetParent(); // Returns parent as IComItemPtr
}
Or:
IDispatchPtr func()
{
return m_pItem->GetParent(); // Returns parent as IComItemPtr converted to IDispatchPtr
}
If you absolutely must return a raw IDispatch* pointer, then you have to either:
manually increment the refcount before exiting:
LPDISPATCH func()
{
IComItemPtr pItem = m_pItem->GetParent(); // Returns parent as IComItemPtr
pItem.AddRef();
return pItem;
}
manually detach the pointer from the wrapper:
LPDISPATCH func()
{
IComItemPtr pItem = m_pItem->GetParent(); // Returns parent as IComItemPtr
return pItem.Detach();
}