As far as I know, the latest answer to COM pointers in ATL are _com_ptr_t (and _bstr_t, _variant_t). This is also the pointer that's used for the ISomeInterfacePtr typedefs when you #import a COM DLL (#import is a Microsoft extension to VC++).
They work well in STL containers and you even get a clean solution for QueryInterface:
_COM_SMARTPTR_TYPEDEF(ISomething, IID_ISomething);_COM_SMARTPTR_TYPEDEF(IOther, IID_IOther); // Create a new instance using CoCreateInstance()ISomethingPtr something = ISomethingPtr(CLSID_Something);// QueryInterface to another IIDtry { IOtherPtr other = something;}catch(const _com_error &error) { cerr << "QueryInterface failed with HRESULT = " << error.Error();}
Or assign new instances easily:
template<typename Class>inline CComObject<Class> *com_new() { CComObject<Class> *pInstance; CheckError(CComObject<Class>::CreateInstance(&pInstance)); return pInstance;}// Create an instance of a local ATL classISomethingPtr something = com_new<CSomeAtlCoClass>();// Take out the pointer without Release()ingISomething *raw = something.Detach();// Assign a new pointer without AddRef()ingsomething.Attach(new ManuallyImplementedCoClass());
Earlier DirectX SDKs also declared _com_ptr_ts for you if you #included <comdef.h> before d3d9.h, but I believe this is no longer the case.
Personally, I'd stay away from CComPtr, CComBSTR and their companions. Compare the code behind CComPtr and _com_ptr_t and the choice should be rather clear.