首先CComQIPtr是CComPtr的子类,所以CComQIPtr有更多功能。
CComQIPtr多一个IID,模板里需要这个参数,但这个参数是默认参数
下面两种形式都可以
CComQIPtr<IA,IID_IA> spQIIA;
CComQIPtr<IA > spQIIA;
而CComPtr则要
CComPtr<IA > spIA;
CComPtr较简单,但它的代价就是更少的兼容性,下面代码来说明:
假设对象ObjA有接口IA和IB当然还有IUnknown
代码1:
CComPtr<IA > spIA2;
spIA= spIA2; //成功
代码2:
CComPtr<IB> spIB;
spIA= spIB; //成功,因为CComPtr里有这样的操作符,因为一开始就没有IID,所以如需要IID则会采用__uuidof来获取,如果__uuidof获取失败,则会编译失败
template <typename Q>
T* operator=(__in const CComPtr<Q>& lp) throw(){。。。}
代码3:
IB * pB;
IUnknown * pUnK;
spIA= spIB; //失败,没有这个操作符
spIA= pUnK; //失败,没有这个操作符
但
spQIIA = spIB; //成功
spQIIA = pUnK; //成功
因为CComQIPtr里有 T* operator=(__in_opt IUnknown* lp) throw()
代码4:
CComQIPtr<IUnknown, &IID_IUnknown> bbb;
CComQIPtr<IUnknown> bbb;
第二行代码会编译错误,因为第二行编译没有采用特化,采用一般化的形式
CComQIPtr(__in_opt T* lp)
CComQIPtr(__in_opt IUnknown* lp)
由于T= IUnknown,所以以会导致编译错误,
第一行则采用了特化,修改了构造函数
template<>
class CComQIPtr<IUnknown, &IID_IUnknown> : public CComPtr<IUnknown>