这三种类型的封装类都对其封装类型进行包裹,尤其是提供分配内存以及释放内存。在设计思想上不同的是:
CComPtr<T>&CComQIPtr<T>:用于维护COM的接口,
l 对于构造函数和赋值等于,
n 无论传入T还是CComPtr<T>,都直接或间接AddRef(相当郁复制)并不是owner相应的T。也就是说通过构造函数或赋值等于传入的T还是由外部来owner释放。
不addRef直接owner T的办法只有两个:
l 使用Attach,直接owner T(自动释放原有T);
l operator T&,在使用中直接替代T。这样就可以间接修改其包含的T,而不AddRef。(事实上这种情况很常用,需要记得释放原来owner的T)
CComBSTR:用于维护BSTR,
l 对于构造函数和赋值等于,都进行复制。
l 使用Attach,直接owner BSTR(自动释放原有BSTR);
l operator BSTR&,在使用中直接替代BSTR,这样就可以间接修改其包含的BSTR(需要手动释放原有BSTR);
CComVariant:用于维护VARIANT:
l 对于构造函数,
n 传入的大部分值,直接owner(主要是LPSTR,LPCOLESTR和BSTR就owner指针);
n 传入VARIANT,CComVariant&,SAFEARRAY进行复制,在赋值等于时,全部进行复制(不owner);
n 对于IUnknown等调用addRef;
l 对于赋值等于,全部进行复制(自动释放原有VARIANT)
l Attach 是进行复制,而不是owner(自动释放原有VARIANT);
l 继承VARIANT,在使用中直接替代VARIANT,从而可修改其内部的值(需要记得释放VARIANT);
CAutoPtr:用于维护C++指针:
l 对于构造函数,无论传入p还是CAutoPtr<p>,都转移ownership;
l 对于赋值等于,只实现了对CAutoPtr<P>或CAutoPtr<p2>,都转移ownership(自动释放原有p);
l Attach转移ownership(不释放原有p)(之所以这样做据说是为了用户不会丢失attach的内容)。
l 没有operator p,但是指针public,可直接访问;
事实上,个人认为,CComVariant和CAutoPtr的设计行为存在问题,
为什么CComBSTR和CComVariant设计行为不一致?说实话, CComBSTR比较正常,CComVariant的行为实在挺烂的。其构造函数和赋值等于行为居然不一样,也不提醒一声,很容易让人弄错了。
CAutoPtr的Attach也挺诡异,容易让用户忘记Free。