我为Internet Explorer(BHO)编写了附加组件,并且正在使用CComPtr智能指针。我想知道:
在这个this链接中,它用于发布
浏览器对象。我还应该在其他地方使用它?在“正常”使用中(与我自己的类(class)一起使用),我不需要它。我应该在这种情况下使用它:
我使用m_spWebBrowser-> get_Document(&spDispDoc)获取文档对象:
无效STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch * pDisp,VARIANT * pvarURL)
{
//查询IWebBrowser2接口(interface)。
CComQIPtr spTempWebBrowser = pDisp;
//此事件与顶级浏览器相关联吗?
如果(spTempWebBrowser && m_spWebBrowser &&
m_spWebBrowser.IsEqualObject(spTempWebBrowser)
{
//从浏览器获取当前文档对象...
CComPtr spDispDoc;
hr = m_spWebBrowser-> get_Document(&spDispDoc);
如果(成功(小时))
{
//...并查询HTML文档。
CComQIPtr htmlDoc2 = spDispDoc;
m_spHTMLDocument = spHTMLDoc;
}
}
}
我应该像使用m_spWebBrowser一样在SetSite函数中释放spHTMLDocument吗(就像前面提到的链接一样)?
CComPtr getObjects(CComQIPtr htmlDoc3)
{
CComPtr对象;
hr = htmlDoc3-> getElementsByTagName(CComBSTR(L“object”),&objects);
if(SUCCEEDED(hr)&&对象!= NULL)
{
返回对象;
}
返回NULL;
}
void RemoveImages(IHTMLDocument2 * pDocument);
但使用智能指针调用:
CComQIPtr spHTMLDoc = spDispDoc;
如果(spHTMLDoc!= NULL)
{
//最后,删除图像。
RemoveImages(spHTMLDoc);
}
我宁愿这样写:
void RemoveImages(CComPtr document2);
这个会比较好吗?
最佳答案
第一个问题。 CComPtr::Release()
与为对象分配空指针具有相同的效果。如果出于某种原因要在指针超出作用域之前释放对象,则可以调用Release()
(或分配空指针)。例如:
CComPtr<ISomeInterface> pointer;
HRESULT hr = firstProvider->GetObject( &pointer );
if( SUCCEEDED( hr ) ) {
//use the object
pointer.Release();
}
HRESULT hr = secondProvider->GetObject( &pointer );
if( SUCCEEDED( hr ) ) {
//use the object
}
您会看到,当
GetObject()
获得指针时,它将覆盖已经存储在CComPtr
中的值。如果CComPtr
存储一个非空指针,它将被覆盖(浅拷贝),并且原始指针指向的对象将被泄漏。您不需要第一个Release()
之前的GetObject()
-指针在该点为null。而且您也不需要在第二个GetObject()
之后-一旦指针超出范围,该对象将被重新分配位置。到第二个问题。是的,您可以返回
CComPtr
,但前提是调用者也将它接受为CComPtr
。如下代码:ISomeInterface* pointer = YourFunctionReturningCComPtr();
不会拥有该对象的所有权,因此该对象将被释放,并且
pointer
将变得悬而未决。那是未定义的行为。对于第三个问题,
CComPtr
是关于所有权的。通常没有必要将CComPtr
作为“输入”参数传递,除非您知道为什么要这么做。关于c++ - 有关使用CComPtr的一些问题(何时使用Release()?我可以返回CComPtr吗?,...),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4284621/