What is the use of CComPtr over CComQIPtr in COM?

Ramesh picture Ramesh · Jul 27, 2011 · Viewed 10.2k times · Source

Can any one explain, What is the use of CComPtr over CComQIPtr in COM?

CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;

Answer

sharptooth picture sharptooth · Jul 27, 2011

CComQIPtr is for cases when you want to call QueryInterface() in a convenient manner to know whether an interface is supported:

IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
   //supported - use
}

This way you can request an interface from a pointer to any (unrelated) COM interface and check whether that request succeeded.

CComPtr is used for managing objects that surely support some interface. You use it as a usual smart pointer with reference counting. It is like CComQIPtr, but doesn't allow the usecase described above and this gives you better type safety.

This code:

IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );

compiles and maybe yields a null pointer if unknown is bound to an object that doesn't implement IDispatch. You now have to check for that in runtime which is good if you wanted a runtime check in the first place but bad if you'd prefer a compile time type check.

This code:

IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );

will simply not compile - it yields

error C2664: 'ATL::CComPtr::CComPtr(IDispatch *) throw()' : cannot convert parameter 1 from 'IUnknown *' to 'IDispatch *'

which provides for better compile time type safety.