visual-c++ com atl smart-pointers

visual c++ - ¿Cuál es el uso de CComPtr sobre CComQIPtr en COM?



visual-c++ atl (5)

"ATL utiliza CComQIPtr y CComPtr para administrar punteros de interfaz COM. Ambas clases realizan recuentos de referencia automáticos mediante llamadas a AddRef y Release. Los operadores sobrecargados manejan las operaciones de puntero. CComQIPtr también admite la consulta automática de interfaces mediante QueryInterface".

¿Y dónde usas uno sobre el otro?

Cuando no desee llamar a ''QueryInterface ()'' ''manualmente'', use ''CComQIPtr'':

CComQIPtr( T* lp ); CComQIPtr( const CComQIPtr< T, piid >& lp );

Si pasa un tipo de puntero derivado de T, el constructor establece p para el parámetro T * y llama a AddRef. Si pasa un tipo de puntero no derivado de T, el constructor llama a QueryInterface para establecer p a un puntero de interfaz correspondiente a piid.

¿Alguien puede explicar, cuál es el uso de CComPtr sobre CComQIPtr en COM?

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



Observación en la respuesta de sharptooth. Solo intenté compilar algo. me gusta

CComQIPtr<IInterface2> to( from );

y fallado Asignación trabajada:

CComQIPtr<IInterface2> to = from;

Desafortunadamente no tengo tiempo para analizar esto más ...


CComQIPtr es para casos en los que desea llamar a QueryInterface() de manera conveniente para saber si una interfaz es compatible:

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

De esta forma, puede solicitar una interfaz desde un puntero a cualquier interfaz COM (no relacionada) y verificar si esa solicitud fue exitosa.

CComPtr se usa para administrar objetos que seguramente son compatibles con alguna interfaz. Lo usa como un puntero inteligente habitual con recuento de referencias. Es como CComQIPtr , pero no permite el uso que se describe arriba y esto le proporciona un mejor tipo de seguridad.

Este código:

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

compila y tal vez produce un puntero nulo si unknown está vinculado a un objeto que no implementa IDispatch . Ahora debe verificarlo en tiempo de ejecución, lo que es bueno si primero quiere un control de tiempo de ejecución pero malo si prefiere una verificación de tipo de tiempo de compilación.

Este código:

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

simplemente no compilará - rinde

error C2664: ''ATL :: CComPtr :: CComPtr (IDispatch *) throw ()'': no ​​se puede convertir el parámetro 1 de ''IUnknown *'' a ''IDispatch *''

que proporciona una mejor seguridad del tipo de tiempo de compilación.


template<class T, const IID* piid = &__uuidof(T)> class CComQIPtr: public CComPtr<T>

Former deduce automáticamente el UUID del tipo dado, a través del argumento de plantilla predeterminado.