在COM中,CComPtr比CComQIPtr有什么用



任何人都能解释一下,在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对应的接口指针。

相关内容

  • 没有找到相关文章

最新更新