0

我声明了一个COM接口,并且我有两个接口的实现(类),具体取决于输入配置。我还有一个工厂方法,可以检查输入配置并在类上适当地调用 NEW。在我的课堂上,我AddRef()按照Release()规范COM实施。我声明一个ComPtr并调用工厂方法来访问上面的接口。我可以通过两种方式做到这一点,

1) 从 Factory 方法返回 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);

从上述调用返回后,Ref 计数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) 会导致 memleak,因为 ref 计数不会变为 0。

4

1 回答 1

0

WRLComPtr实例在您的那一刻自动增加参考计数器

new CCaptureSource1()

转换为返回

ComPtr<ICaptureSource>

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

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

于 2019-11-04T09:26:02.403 回答