任何人都能解释一下,在COM中,CComPtr比CComQIPtr有什么用吗?
CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;
CComQIPtr
适用于希望以方便的方式调用QueryInterface()
以了解是否支持接口的情况:
IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
//supported - use
}
通过这种方式,您可以从指向任何(不相关的(COM接口的指针请求接口,并检查该请求是否成功。
CComPtr
用于管理肯定支持某些接口的对象。您可以将其用作具有引用计数的普通智能指针。它类似于CComQIPtr
,但不允许使用上面描述的用例,这为您提供了更好的类型安全性。
此代码:
IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );
如果unknown
绑定到未实现IDispatch
的对象,则编译并可能产生空指针。现在,您必须在运行时检查这一点,如果您首先想要运行时检查,这是好的,但如果您更喜欢编译时类型检查,这就不好了。
此代码:
IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );
根本不会编译-它会产生
错误C2664:"ATL::CComPtr::CComPtr(IDispatch*(throw((":无法将参数1从"IUnknown*"转换为"IDispatch*">
这提供了更好的编译时类型安全性。
template<class T,
const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>
前者通过默认模板参数自动推导给定类型的UUID。
下面的MSDN文章解释了差异,并建议使用CComPtr而不是CComQIPtr
如何:创建和使用CComPtr和CComQIPtr实例
关于锐齿答案的备注。只是试图编译类似的东西
CComQIPtr<IInterface2> to( from );
并且失败了。任务反而奏效了:
CComQIPtr<IInterface2> to = from;
不幸的是,我没有时间对此进行进一步分析。。。
"ATL使用CComQIPtr和CComPtr来管理COM接口指针。这两个类都通过调用AddRef和Release来执行自动引用计数。重载运算符处理指针操作。CComQIPtr还支持通过QueryInterface自动查询接口。">
你在哪里使用一个而不是另一个?
当您不想"手动"调用"QueryInterface(("时,请使用"CComQIPtr":
CComQIPtr( T* lp );
CComQIPtr( const CComQIPtr< T, piid >& lp );
如果传递从T派生的指针类型,则构造函数将p设置为T*参数并调用AddRef。如果传递的指针类型不是从T派生的,则构造函数调用QueryInterface将p设置为与piid对应的接口指针。