vc备忘:COM指针

Posted by 妖刀 5 January, 2008

一、标准模式
调用某个函数或方法,返回接口指针,在某个时间范围内使用这个接口指针,然后释放它。下面是使用这种模式的代码例子:

void f(void) {
IUnknown *pUnk = 0;
// 调用
HRESULT hr = GetSomeObject(&pUnk);
if (SUCCEEDED(hr)) {
// 使用
UseSomeObject(pUnk);
// 释放
pUnk->Release();
}
}

二、CComPtr
CComPtr类实现客户端基本的COM引用计数模型。CComPtr有一个数据成员,它是一个未经过任何加工的COM接口指针。其类型被作为模板参数传递:

CComPtr unk;
CComPtr cf;

缺省的构造函数将这个原始指针数据成员初始化为NULL。
CComPtr智能指针在析构时自动Release。

三、CComQIPtr
CComQIPtr与CComPtr关系很密切(实际上,它只增加了两个成员函数)。CComQIPtr必须要两个模板参数:一个是被操纵的指针类型 ,另一个是对应于这个指针类型的GUID。例如,下列代码声明了操纵IDataObject 和IPersist接口的智能指针:

CComQIPtr do;
CComQIPtr p;

CComQIPtr的优点是它有重载的构造函数和赋值操作符。同类版本(例如,接受相同类型的接口)仅仅AddRef右边的赋值/初始化操作。这实际上就是CComPtr的功能。异类版本(接受类型不一致的接口)正确调用QueryInterface来决定是否这个对象确实支持所请求的接口:

void f(IPersist *pPersist) {
CComQIPtr p;
// 同类赋值 - AddRef''s
p = pPersist;

CComQIPtr do;
// 异类赋值 - QueryInterface''s
do = pPersist;
}

再比如:

CComQIPtr psDocment;
CComPtr psDisp;
m_pWebBrowser2->get_Document(&psDisp);
psDocment = psDisp; // 这里自动调用QueryInterface

Categories : 技术 / 设计 Tags :

Trackbacks & Pingbacks
Comments
Leave a comment

(required)

(required)