I declared a COM
interface and I have two implementations(classes) of the interface depending on input config. I also have a factory method that checks for input config and appropriately calls NEW on the class. In my class I implement AddRef()
and Release()
as per COM
spec.
I declare a ComPtr
and call the factory method to get access to above interface. I can do this two ways,
1) Return ComPtr from Factory method
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);
After returning from above call, Ref count of captureSource
is '2'. I was expecting it to be 1.
However with below code, Ref count is 1
2) Pass ComPtr
address as parameter to factory method
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
ref count is now 1.
Kindly guide me why is there a difference in ref count in above two approaches and why returning an object is incrementing ref count (2), Vs setting object pointer to *ppv
(ref count 1).
As it can be expected, approach (1) is causing memleak because ref count does not go to 0.