我正在为 Internet Explorer (BHO) 编写附加组件,并且正在使用 CComPtr 智能指针。我想知道:
- 我什么时候应该使用 CComPtr.Release() 函数?
- 我可以从函数安全地返回 CComPtr 吗? 我的意思是这样的:
- 我永远不应该使用普通指针吗? 在前面的链接中,RemoveImages 私有(private)函数是这样声明的:
在这个this用于发布的链接 浏览器对象。我还应该在哪里使用它?在“正常”使用中(使用我自己的类(class))我不需要它。我应该在这种情况下使用它吗:
我使用 m_spWebBrowser->get_Document(&spDispDoc) 获取文档对象:
void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL) { // Query for the IWebBrowser2 interface. CComQIPtr spTempWebBrowser = pDisp; // Is this event associated with the top-level browser? if (spTempWebBrowser && m_spWebBrowser && m_spWebBrowser.IsEqualObject(spTempWebBrowser)) { // Get the current document object from browser... CComPtr spDispDoc; hr = m_spWebBrowser->get_Document(&spDispDoc); if (SUCCEEDED(hr)) { // ...and query for an HTML document. CComQIPtr htmlDoc2 = spDispDoc; m_spHTMLDocument = spHTMLDoc; } } }我是否应该像使用 m_spWebBrowser 那样在 SetSite 函数中释放 spHTMLDocument(如前面提到的链接)?
CComPtr getObjects(CComQIPtr<IHTMLDocument3> htmlDoc3) { CComPtr objects; hr = htmlDoc3->getElementsByTagName(CComBSTR(L"object"), &objects); if(SUCCEEDED(hr) && objects != NULL) { return objects; } return NULL; }
void RemoveImages(IHTMLDocument2 *pDocument);但使用智能指针调用:
CComQIPtr<IHTMLDocument2> spHTMLDoc = spDispDoc; if (spHTMLDoc != NULL) { // Finally, remove the images. RemoveImages(spHTMLDoc); }我宁愿这样写:
void RemoveImages(CComPtr<IHTMLDocument2> 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
存储一个非空指针,它将被覆盖(浅拷贝)并且原始指针指向的对象将被泄漏。在第一个 GetObject()
之前不需要 Release()
- 此时指针为空。在第二个 GetObject()
之后您不需要任何一个 - 一旦指针超出范围,该对象将被释放。
第二个问题。是的,您可以返回 CComPtr
,但前提是调用方也将其接受到 CComPtr
中。以下代码:
ISomeInterface* pointer = YourFunctionReturningCComPtr();
不会取得该对象的所有权,因此该对象将被释放,指针
将变为悬挂状态。这是未定义的行为。
第三个问题 CComPtr
是关于所有权的。通常,将 CComPtr
作为“输入”参数传递是没有意义的,除非您确切地知道为什么要这样做。
关于c++ - 关于使用CComPtr的一些问题(什么时候使用Release()?我可以返回CComPtr吗?,...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4284621/