The only time that delete should be needed on a COM object from outside the class is if you implement IClassFactory yourself, use new to allocate the memory for a requested object but an IID is requested that the object does not support. In that case the reference count will still be zero and you need to delete the (arguably potential rather than actual) COM object before returning. It would be a real c++ object at that point (after new before delete) but not a real COM object despite all appearances, all other cases should use Release.
Even there you could make it a real COM object by calling QueryInterface for IID_IUnknown and using that interface pointer to query for whatever the IID passed to CreateInstance was rather than directly using the class object pointer. And if you follow that pattern all deletes would be through the Release method (because the IUnknown used for the query would need releasing) and there would be no other references.
However implementing IClassFactory (or even IUnknown) yourself is generally silly, there are plenty of frameworks out there (ATL for one) that make getting the fiddly details of COM (aggregation in particular) right so much easier.