我为Internet Explorer(BHO)编写了附加组件,并且正在使用CComPtr智能指针。我想知道:

  • 什么时候应该使用CComPtr.Release()函数?

  • 在这个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吗?
  • 我的意思是这样的:
    CComPtr getObjects(CComQIPtr htmlDoc3)
    {
    CComPtr对象;
    hr = htmlDoc3-> getElementsByTagName(CComBSTR(L“object”),&objects);
    if(SUCCEEDED(hr)&&对象!= NULL)
    {
    返回对象;
    }
    返回NULL;
    }
  • 我应该永远不要使用普通指针吗?
  • 在上一个链接中,RemoveImages私有(private)函数是这样声明的:
    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/

    10-11 16:08