CComPtr在CC中使用CComQIPtr有什么用?

Ram*_*esh 18 com atl smart-pointers visual-c++

任何人都可以解释一下,CComPtr在CC中使用CComQIPtr有什么用?

CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;
Run Code Online (Sandbox Code Playgroud)

sha*_*oth 25

CComQIPtr适用于您希望以QueryInterface()方便的方式调用以了解是否支持接口的情况:

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

这样,您可以从指向任何(不相关的)COM接口的指针请求接口,并检查该请求是否成功.

CComPtr用于管理肯定支持某些接口的对象.您可以将它用作带引用计数的常用智能指针.它就像CComQIPtr,但不允许上面描述的用例,这样可以提供更好的类型安全性.

这段代码:

IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );
Run Code Online (Sandbox Code Playgroud)

编译并且如果unknown绑定到未实现的对象,则可能产生空指针IDispatch.您现在必须在运行时检查它,如果您想要首先进行运行时检查,那么这是好的,但如果您更喜欢编译时类型检查则会很糟糕.

这段代码:

IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );
Run Code Online (Sandbox Code Playgroud)

将不会编译 - 它产生

错误C2664:'ATL :: CComPtr :: CComPtr(IDispatch*)throw()':无法将参数1从'IUnknown*'转换为'IDispatch*'

这提供了更好的编译时类型安全性.


Aja*_*jay 2

template<class T,
   const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>
Run Code Online (Sandbox Code Playgroud)

前者通过默认模板参数自动推导出给定类型的 UUID。