Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么从方法返回时COM智能指针会被删除_C++_Com - Fatal编程技术网

C++ 为什么从方法返回时COM智能指针会被删除

C++ 为什么从方法返回时COM智能指针会被删除,c++,com,C++,Com,为什么我的COM智能指针在我从func返回时尝试删除。我认为它仍然在范围之内。有没有办法避免这种情况 这是.TLH文件中的定义 _COM_SMARTPTR_TYPEDEF(IComItem, __uuidof(IComItem)); 函数的返回类型是原始的IDispatch*指针,而不是IComItemPtr对象(或者至少是IDispatchPtr对象)。您看到的问题是由于您错误地将智能指针与原始指针混合 由于函数不返回智能包装器对象,因此必须执行转换以将pItem转换为IDispatch*

为什么我的COM智能指针在我从func返回时尝试删除。我认为它仍然在范围之内。有没有办法避免这种情况

这是.TLH文件中的定义

_COM_SMARTPTR_TYPEDEF(IComItem, __uuidof(IComItem));


函数的返回类型是原始的
IDispatch*
指针,而不是
IComItemPtr
对象(或者至少是
IDispatchPtr
对象)。您看到的问题是由于您错误地将智能指针与原始指针混合

由于函数不返回智能包装器对象,因此必须执行转换以将
pItem
转换为
IDispatch*
。在这种情况下,
pItem
可以执行的是
IComItem*
,然后编译器可以隐式地将其转换为
IDispatch*
(因为
IComItem
派生自
IDispatch
,否则您的代码根本不会编译)

注意,您的
return
语句有效地执行了以下逻辑:

LPDISPATCH func()
{
    IComItemPtr  pItem = m_pItem;

    pItem = pItem->GetParent();  // Returns parent as IComItemPtr

    //return pItem;
    IComItem *pTemp = pItem.operator IComItem*();
    IDispatch *pDisp = (IDispatch*) pTemp;
    return pDisp;

} // <-- pItem is destructed here!
或:

如果绝对必须返回原始
IDispatch*
指针,则必须:

  • 退出前手动增加refcount:

    LPDISPATCH func()
    {
        IComItemPtr pItem = m_pItem->GetParent();  // Returns parent as IComItemPtr
        pItem.AddRef();
        return pItem;
    }
    
  • 从包装器中手动分离指针:

    LPDISPATCH func()
    {
        IComItemPtr pItem = m_pItem->GetParent();  // Returns parent as IComItemPtr
        return pItem.Detach();
    }
    

    • 你的第一个假设是不正确的

      static IComItemPtr m_pItem;
      
      LPDISPATCH func()
      {
          IComItemPtr  pItem = m_pItem;
      
          pItem = pItem->GetParent();
      
          return pItem;  // not here.
      
      }   // Gets deleted here (this is where scope is closed).
      
      在调用析构函数之前,返回将把pItem从IComItemPtr转换为LPDISPATCH(
      IDispatch*
      )。此转换的结果将放置在目标中

      注意:转换的方式将完全取决于所涉及类型的确切定义

      LPDISPATCH func()
      {
          IComItemPtr pItem = m_pItem->GetParent();  // Returns parent as IComItemPtr
          pItem.AddRef();
          return pItem;
      }
      
      LPDISPATCH func()
      {
          IComItemPtr pItem = m_pItem->GetParent();  // Returns parent as IComItemPtr
          return pItem.Detach();
      }
      
      static IComItemPtr m_pItem;
      
      LPDISPATCH func()
      {
          IComItemPtr  pItem = m_pItem;
      
          pItem = pItem->GetParent();
      
          return pItem;  // not here.
      
      }   // Gets deleted here (this is where scope is closed).