从工厂方法返回的 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
实例将附加指针而不递增,但它会在销毁时递减。这就是引用计数器达到零的方式。
我声明了一个 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
实例将附加指针而不递增,但它会在销毁时递减。这就是引用计数器达到零的方式。