从工厂方法返回的 ComPtr 的引用计数递增两次

Reference count of ComPtr returned from a factory method is incremented twice

我声明了一个 COM 接口,根据输入配置,我有两个接口实现(classes)。我还有一个检查输入配置并在 class 上适当调用 NEW 的工厂方法。在我的 class 中,我按照 COM 规范实现了 AddRef()Release()。 我声明了一个 ComPtr 并调用工厂方法来访问上面的接口。我可以通过两种方式做到这一点,

1) Return 来自工厂方法的 ComPtr

ComPtr<ICaptureSource> ICaptureSource::CreateInstance(someConfig)
{
   switch (someConfig)
   {
     case 1:
          return (new CCaptureSource1());  >> Ref count in this class is initialized to 1 
          break;
     case 2:
          return (new CCaptureSource2());  >> Ref count in this class is initialized to 1 
           break;
     default:
          return nullptr;
   }

}


ComPtr <ICaptureSource> captureSource;

captureSource = ICaptureSource::CreateInstance(someConfig);

从上述调用返回后,captureSource 的引用计数为“2”。我原以为它是 1。

但是使用下面的代码,引用计数是 1

2) 将ComPtr 地址作为参数传递给工厂方法

HRESULT ICaptureSource::CreateInstance(someConfig, ICapturesource **ppv)
{
   ICaptureSource *pTemp = nullptr;
   switch (someConfig)
   {
     case 1:
          pTemp = new CCaptureSource1();  >> Ref count in this class is initialized to 1 
          break;
     case 2:
          pTemp = new CCaptureSource2();  >> Ref count in this class is initialized to 1 
           break;
   }

  if (SUCCEEDED(hr) && (ppv != nullptr))
  {
     *ppv = pTemp;
  }
  return hr
}

ComPtr <ICaptureSource> captureSource;

hr = ICaptureSource::CreateInstance(someConfig, &captureSource);

captureSource 引用计数现在为 1。

请指导我为什么上述两种方法的引用计数不同,为什么返回对象会增加引用计数 (2),而不是将对象指针设置为 *ppv(引用计数 1)。

正如所料,方法 (1) 导致内存泄漏,因为引用计数没有变为 0。

WRL ComPtr 实例在您的

时刻自动增加引用计数器

new CCaptureSource1()

转换为返回

ComPtr<ICaptureSource>

这是设计使然并记录在案的行为(“...自动维护底层接口指针的引用计数...”)。当您的 captureSource 变量超出范围时,您的对象的引用计数将减少。

在你的第二种方法中,你将一个原始接口指针附加到 ComPtr 实例中:你将一个原始(意思是:不由智能指针 class 递增)指针放入 *ppv 中,所以参考计数器仍然是一个。 ComPtr 实例将附加指针而不递增,但它会在销毁时递减。这就是引用计数器达到零的方式。